zoukankan      html  css  js  c++  java
  • 【纪中集训2019.3.12】Z的礼物

    题意

    已知(a_{i} = sum_{j=1}^{i} {^{i} _{j} }b_{j}), 给出(a_{1} 到 a_{n})

    (b_{l} 到 b_{r})(1e9+7)的意义下取模的值;

    (1 le l le r le n le 10^5)

    (r-l le 100)

    (0 le a_{i} lt 10^9 + 7)

    题解

    • Part1

    • 斯特林反演(https://www.cnblogs.com/hchhch233/p/10016543.html):

      • (f(n) = sum_{i=1}^{n} {^n_i} g(n) Longleftrightarrow g(n) = sum_{i=1}^{n} (-1)^{n-i} [^n_i]f(i))
    • 由于(r-l)比较小,可以直接暴力求,只需要快速求出([^n_1] - [^n_n])

    • ([_m^n] = [x^m] x^{overline n}) , 其中(x^{overline n} = Pi_{i=1}^n(x+i-1))

    • Part 2

    • 直接做是(n log ^2n)的,假设在计算(F_n(x) = x^{overline n})时已经计算了(F_frac{n}{2}(x)),记(m = frac{n}{2} , F_{m} = sum_{i=0}^{m}a_{i} x^{i})

    • 只需要计算(F'_{m} (x) = F_{m}(x+m))(F_{m})相乘;

    • [F'_m(x) = sum_{i=0}^{m} a_{i} (x+m)^i \ = sum_{i=0}^{m} a _{i}sum_{j=0}^{i}(^i_j)x^j m^{i-j} \ = sum_{i=0}^{m} sum_{j=0}^{i} a_{i} frac{i!}{j!(i-j)!}x^{j}m^{i-j} \ = sum_{i=0}^{m} frac{x^i}{i!} sum_{j=0}^{m-i} a_{i+j}(i+j)! frac{m^{j}}{j!} ]

    • 记$A(x)=sum_{i=0}^{m} a_{i} i! x^{i}, B(x) = sum_{i=0}^{m}frac{m^{i}}{i!} x^{m-i} $

    • 相乘之后取第(m+i)项可以算后面的东西

    • Part 3

    • 可是不是(ntt)模数,直接取模会爆(long long)需要用到拆系数(ntt);

    • (A(x)*B(x))分解成((k * A1(x) + A2(x)) * (k * B1(x) + B2(x)) , k 一般取sqrt{n} (2^{15} ) 左右)

    • 暴力是7次(fft),可以优化到需要4次(fft)

    • 两次(fft)合并成一次的做法,需要计算(dft(A(x))和dft(B(x)))

    • 记: $$egin{align} P(x) = A(x) + iB(x) Q(x) = A(x) -iB(x) end{align}$$

    • 考虑直接做(P)(P’),考虑(Q dft)之后的结果(Q')

      [egin{align} Q'[k] &= A(w_{n}^{k}) - iB(w_{n}^{k}) \ &= sum_{j=0}^{n-1} (a_{j}-ib_{j})w^{jk}_{n} \ &= sum_{j=0}^{n-1}(a_{j}-ib_{j})(cos(frac{2pi jk}{n} ) + isin(frac{2pi jk}{n}) ) \ &= sum_{j=0}^{n-1}(a_{j}cos(frac{2pi jk}{n}) + b_{j}sin(frac{2pi jk}{n}))- i(b_{j}cos(frac{2pi jk}{n}) - a_{j}sin(frac{2pi jk}{n})) \ &= conj sum_{j=0}^{n-1} (a_{j}cos(frac{-2pi jk}{n}) - b_{j}sin(frac{-2pi jk}{n} ) ) +i( b_{j}cos(frac{-2pi jk}{n}) + a_{j}sin(frac{-2pi jk}{n})) \ &= conj sum_{j=0}^{n-1} (a_{j}+ib_{j})(cos(frac{-2pi jk}{n})+isin(frac{-2pi jk}{n})) \ &= conj sum_{j=0}^{n-1} (a_{j}+ib_{j})w^{-jk}_{n} \ &= conj P'[n-k] end{align} ]

    • 所以由(P')直接得到(Q'):

    • 即:$$ egin{align} A'(x) = frac{P'(x) + Q'(x)}{2} B'(x) = frac{P'(x) - Q'(x)}{2i}end{align} g $$

    • 结果也存在实部和虚部里直接(idft)回去就好了;

    • 注意精度;

      #include<bits/stdc++.h>
      #define ld long double
      #define ll long long 
      using namespace std;
      const int N=400010,mod=1e9+7;
      const ld pi=acos(-1);
      int n,l,r,rev[N],fac[N],inv[N],p[N],a[N],b[N];
      char gc(){
      	static char*p1,*p2,s[1000000];
      	if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
      	return(p1==p2)?EOF:*p1++;
      }
      int rd(){
      	int x=0;char c=gc();
      	while(c<'0'||c>'9')c=gc();
      	while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
      	return x;
      }
      int pw(int x,int y){
      	int re=1;
      	while(y){
      		if(y&1)re=(ll)re*x%mod;
      		y>>=1,x=(ll)x*x%mod;
      	}
      	return re;
      }
      struct C{
      	ld x,y;
      	C(ld _x=0,ld _y=0):x(_x),y(_y){};
      	C operator +(const C&A)const{return C(x+A.x,y+A.y);}
      	C operator -(const C&A)const{return C(x-A.x,y-A.y);}
      	C operator *(const C&A)const{return C(x*A.x-y*A.y,x*A.y+y*A.x);}
      	C operator /(const ld&A)const{return C(x/A,y/A);}
      	C operator !()const{return C(x,-y);}
      };
      void fft(C*A,int len,int f){
      	for(int i=0;i<len;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
      	for(int i=1;i<len;i<<=1){
      		C wn=C(cos(pi/i),f*sin(pi/i));
      		for(int j=0;j<len;j+=i<<1){
      			C w=C(1,0);
      			for(int k=0;k<i;++k,w=w*wn){
      				C x=A[j+k],y=w*A[j+k+i];
      				A[j+k]=x+y,A[j+k+i]=x-y;
      			}
      		}
      	}
      	if(!~f){for(int i=0;i<len;++i){A[i]=A[i]/len;}}
      }
      void mul(int*A,int*B,int n){
      	static C t1[N],t2[N],t3[N],t4[N];
      	int L,len;
      	for(L=0,len=1;len<(n+1)<<1;++L,len<<=1);
      	for(int i=0;i<len;++i){rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));}
      	for(int i=0;i<=n;++i)t1[i]=C(A[i]>>15,A[i]&0x7fff),t2[i]=C(B[i]>>15,B[i]&0x7fff);
      	for(int i=n+1;i<len;++i)t1[i]=t2[i]=C(0,0);
      	fft(t1,len,1),fft(t2,len,1);
      	for(int i=0;i<len;++i){
      		C x1=t1[i],y1=!t1[(len-i)&(len-1)];
      		C x2=t2[i],y2=!t2[(len-i)&(len-1)];
      		t3[i]=(x1+y1)*x2*C(0.5,0);
      		t4[i]=(x1-y1)*x2*C(0,-0.5);
      	//	t3[i]=((x1+y1)*(x2+y2)+(x1+y1)*(x2-y2))*C(0.25,0);
      	//	t4[i]=((x1-y1)*(x2+y2)+(x1-y1)*(x2-y2))*C(0,-0.25);
      	}
      	fft(t3,len,-1),fft(t4,len,-1);
      	for(int i=0;i<=n<<1;++i){
      		A[i]=((((ll)(t3[i].x+0.1)%mod)<<30)+(((ll)(t3[i].y+t4[i].x+0.1)%mod)<<15)+(ll)(t4[i].y+0.1))%mod;
      	}
      }
      void solve(int*A,int n){
      	if(n==0){A[0]=1;return;}
      	if(n==1){A[1]=1;return;}
      	if(n&1){
      		solve(A,n-1);
      		for(int i=n;i;--i)A[i]=(A[i-1]+(ll)A[i]*(n-1))%mod;
      		A[0]=0; 
      		return;
      	}
      	static int t1[N],t2[N];
      	int m=n>>1;
      	solve(A,m);
      	for(int i=0;i<=m;++i)t1[i]=(ll)A[i]*fac[i]%mod;
      	for(int i=0,t=1;i<=m;++i,t=(ll)t*m%mod)t2[m-i]=(ll)t*inv[i]%mod;
      	mul(t1,t2,m);
      	for(int i=0;i<=m;++i){t1[i]=(ll)inv[i]*t1[m+i]%mod;}
      	mul(A,t1,m);
      }
      int main(){
      	freopen("gift.in","r",stdin);
      	freopen("gift.out","w",stdout);
      	n=rd();l=rd();r=rd();
      	for(int i=1;i<=n;++i)p[i]=rd();
      	for(int i=fac[0]=inv[0]=1;i<=n;++i){
      		fac[i]=(ll)fac[i-1]*i%mod;
      		inv[i]=pw(fac[i],mod-2);
      	}
      	solve(a,l-1);
      	for(int i=l-1;i<=r;++i){
      		for(int j=1;j<=i;++j){
      			int t=(ll)a[j]*p[j]%mod;
      			if((i-j)&1)b[i]=(b[i]-t+mod)%mod; 
      			else b[i]=(b[i]+t)%mod;
      		}
      		for(int j=i+1;j;--j){a[j]=(a[j-1]+(ll)a[j]*i)%mod;}a[0]=0;
      	//	b[i]=(b[i]-b[i-1]+mod)%mod;
      	}
      	for(int i=l;i<=r;++i)printf("%d ",(b[i]-b[i-1]+mod)%mod);
      	return 0;
      }
      
  • 相关阅读:
    二叉树的序列化与反序列化
    寻找重复的子树
    [ABC216H] Random Robots
    Codeforces Round #741 (Div. 2)
    [Gym 102798K] Tree Tweaking
    CF798E Mike and code of a permutation
    CF1149E Election Promises
    [BZOJ 4311] 向量
    CF1268D Invertation in Tournament
    [做题笔记] 浅谈势能线段树在特殊区间问题上的应用
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10519990.html
Copyright © 2011-2022 走看看