标签:
常数优化数次后终于卡过去了,感人肺腑。成功get rank last。
orz出题人clj:
http://download.noi.cn/T/2014/CCF_CTSC2014.rar 解压密码CCfCtsC2014
orz神犇们的题解以及常数优化技巧:
http://blog.miskcoo.com/2015/05/bzoj-3557
http://cjjlsdy.blog.163.com/blog/static/180370563201461133026/
http://picks.logdown.com/posts/197310-solution-to-ctsc2014-random
http://vfleaking.blog.163.com/blog/static/1748076342014421105221134/
顺便吐槽一句对拍的时候发现这几份代码输出不一样。
简要说一下做法:
每个数可以看做GF(2)下的多项式,则mk=m0*x^k (mod x^m+X)。
需要多项式取模,blog.miskcoo.com及picks.logdown.com里有讲解。
那么第一问FFT+快速幂,第二问由于x是好的,则x是mod x^m+X意义下的群的生成元,那么x=x^2^m,多项式a的逆元即为a^(2^m-2),求个逆元即可。
为优化常数可以在n较小时用压位乘法而不用FFT(orz vfk)
#include<bits/stdc++.h>
#define N (1<<21)
using namespace std;
struct vec{
double x,y;
vec(double x=0,double y=0)
:x(x),y(y){}
};
vec operator+(vec a,vec b){
return vec(
a.x+b.x,a.y+b.y);
}
vec operator-(vec a,vec b){
return vec(
a.x-b.x,a.y-b.y);
}
vec operator*(vec a,vec b){
return vec(
a.x*b.x-a.y*b.y,
a.x*b.y+a.y*b.x);
}
void fft(vec* q,int n,int m){
int i,j,k;
for(i=j=0;i!=n;++i){
if(i<j)
swap(q[i],q[j]);
for(k=n>>1;
(j^=k)<k;k>>=1);
}
for(i=2;i<=n;i<<=1){
double a(2*m
*acos(-1)/i);
vec s(cos(a),sin(a));
for(j=0;j!=n;j+=i){
vec t=1;
for(k=j;k!=j+i/2;
t=t*s,++k){
vec u=q[k];
vec v=t*q[k+i/2];
q[k]=u+v;
q[k+i/2]=u-v;
}
}
}
if(!~m)
for(i=0;i!=n;++i)
q[i].x/=n;
}
int* mem(int k){
return (int*)calloc(k,4);
}
struct pol{
int k,*u;
pol(int v=0,int s=N)
:k(1),u(mem(s)){u[0]=v;}
~pol(){free(u);}
int& operator[](int i){
return u[i];
}
pol& operator=(int v){
k=1,u[0]=v;
return *this;
}
pol& operator=(pol& v){
memcpy(u,v.u,(k=v.k)*4);
return *this;
}
pol& operator+=(pol& v);
pol& operator*=(pol& v);
};
int get(int k){
int i=1;
for(;i<k;i<<=1);
return i;
}
pol& pol::operator+=(pol& v){
for(int i=0;i!=k;++i)
u[i]=u[i]+v[i]&1;
return *this;
}
pol& pol::operator*=(pol& v){
if(!k||!v.k)
return *this=0;
int i,j,n=k,m=v.k;
k+=m-1;
if(k<=1e4){
typedef unsigned
long long ds[200];
static ds s,t;
int q=k+63>>6;
fill(s,s+q,0);
fill(t,t+q,0);
for(i=0;i!=m;++i)
s[i>>6]|=0ull
+v[i]<<(i&63);
for(i=0;i!=n;++i){
if(u[i])
for(j=0;j!=q;++j)
t[j]^=s[j];
for(j=q-1;j;--j)
s[j]=s[j]<<1
|s[j-1]>>63&1;
s[0]<<=1;
}
for(i=0;i!=k;++i)
u[i]=t[i>>6]>>(i&63)&1;
}else{
static vec s[N],t[N];
j=get(k);
copy(u,u+n,s);
copy(v.u,v.u+m,t);
fill(s+n,s+j,0);
fill(t+m,t+j,0);
fft(s,j,1);
fft(t,j,1);
for(i=0;i!=j;++i)
s[i]=s[i]*t[i];
fft(s,j,-1);
for(i=0;i!=k;++i)
u[i]=int(s[i].x+.5)&1;
}
return *this;
}
void mov(pol& a,int k){
if(a.k<k)
fill(a.u+a.k,a.u+k,0);
a.k=k;
}
void inv(pol& u,pol& v,int k){
if(k<=1)v=k;
else{
int m=k+1>>1;
inv(u,v,m);
mov(v*=v,k);
mov(v*=u,k);
}
}
int fix(pol& a){
while(a.k&&!a[a.k-1])
--a.k;
return a.k;
}
void rev(pol& u,pol& v,int k){
reverse_copy(
u.u,u.u+u.k,v.u);
v.k=u.k,mov(v,k);
}
void print(pol& a,
const char* s=""){
printf("%s",s);
for(int i=0;i!=a.k;++i)
printf("%d ",a[i]);
putchar(10);
}
void div(pol& a,pol& b,pol& d,pol& r){
if(fix(a)<fix(b))
d=0,r=a;
else{
static pol u,v;
int k=a.k-b.k+1;
rev(a,d,k);
rev(b,u,k);
inv(u,v,k);
mov(d*=v,k);
reverse(d.u,d.u+k);
r=b,r*=d;
mov(r,b.k-1),r+=a;
}
}
void gcd(pol& a,pol& b,pol& x,pol& y){
if(!fix(b))
x=1,y=0;
else{
pol u(0,1<<11);
pol v(0,1<<11);
div(a,b,u,v);
gcd(b,v,y,x);
u*=x,mov(y,max(
y.k,u.k)),y+=u;
}
}
void mul(pol& a,pol& b,pol& p){
if(!a.k||!b.k){
a=0;return;
}
int i,j,k=a.k+b.k-1;
if(k<p.k){
a*=b;return;
}
if(k<=1e4){
typedef unsigned
long long ds[200];
static ds s,t,u;
int q=k+63>>6;
fill(s,s+q,0);
fill(t,t+q,0);
for(i=0;i!=b.k;++i)
s[i>>6]|=0ull
+b[i]<<(i&63);
for(i=0;i!=p.k;++i)
u[i>>6]|=0ull
+p[i]<<(i&63);
for(i=0;i!=a.k;++i){
if(a[i])
for(j=0;j!=q;++j)
t[j]^=s[j];
for(j=q-1;j;--j)
s[j]=s[j]<<1
|s[j-1]>>63&1;
s[0]<<=1;
if(s[(p.k+63>>6)-1]
>>(p.k-1&63)&1)
for(j=0;j!=q;++j)
s[j]^=u[j];
}
a.k=p.k-1;
for(i=0;i!=a.k;++i)
a[i]=t[i>>6]>>(i&63)&1;
}else{
static pol u,v;
u=a;
div(u*=b,p,v,a);
}
}
void inv(pol& a,int m,pol& p){
static pol u;
u=a,a=1;
while(--m){
mul(u,u,p);
mul(a,u,p);
}
}
template<class T>
inline void scan(T& x){
static int u;
x=0;
while((u=getchar())<48);
do
x=x*10+u-48;
while((u=getchar())>32);
}
int main(){
pol a,m0,u,v,x;
int i,m,l,q;
long long k;
scan(m);
for(i=0;i!=m;++i)
scan(x[i]);
for(i=0;i!=m;++i)
scan(m0[i]);
x.k=m0.k=m;
x[x.k++]=1;
if(scan(q),q){
scan(l);
for(i=0;i!=m;++i)
scan(a[i]);
a.k=m;
inv(u=m0,m,x);
mul(a,u,x);
for(i=0;i!=m-l;++i)
mul(a,a,x);
}else{
a=u[1]=1,u.k=2;
scan(k);
for(;k;k>>=1){
if(k&1)
mul(a,u,x);
if(k>>1)
mul(u,u,x);
}
}
mul(m0,a,x);
for(i=0;i!=m;++i)
putchar(m0[i]+48);
putchar(10);
}
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5556834.html