zoukankan      html  css  js  c++  java
  • 洛谷7111

    第一次想出多项式题。
    其实去年就想出来了,今年再推一遍。
    考虑一个式子,([x^y]prod_{i=1}^n(1+x+x^2+...+x^{a_i}))
    注意到后面和(frac{1}{1-x})长得很像,所以把后面的(1+x+x^2+...+x^{a_i})拆成((1+x+x^2+....)-(x^{a_i+1}+....)=frac{1-x^{a_i+1}}{1-x})
    (b_i=a_i+1)原式(=[x^y]prod_{i=1}^n(frac{1-x^{b_i}}{1-x}))
    考虑询问怎么求。
    注意到在一次询问内,无论(b_i)改成多少,(frac{1}{1-x})的次数永远是(n)
    (p(x)=prod_{i=1}^nfrac{1-x^{b_i}}{1-x})
    先把(p(x))乘以(frac{1}{1-x})表示取前缀和。
    所以询问要我们求的:([x^y]p(x)frac{1-x^z}{1-x^{b_i}}),其中(z)是原题的(x+1)
    把下面展开,就是要我们求([x^y]p(x)(1-x^z)(1+x^{b_i}+x^{2b_i}+.....))
    枚举((1-x^z))取哪个项,则问题转化成(O(q))组询问:(p(x)(1+x^{b_i}+x^{2b_i}+.....))的某项系数。
    实际上就是哈希冲突。
    (b_igeq sqrt{10^5}),由于询问系数是(O(10^5))级别,可以暴力计算。
    (b_i<sqrt{10^5}),由于可能的(b_i)只有(O(sqrt{10^5}))种,可以预处理出每种(b)的答案。
    (f_{i,j})表示(y=i,b_i=j)的答案,可以递推求。
    ([x^y]1-x^{b_i})是个经典问题(付公主的背包),求出((frac{1}{1-x})^{n+1})可以按照生成函数的定义。
    然后把([x^y]1-x^{b_i})乘以((frac{1}{1-x})^{n+1})就是(p)
    最终时间复杂度(O(nsqrt{n}))
    感觉没什么细节,但是不知道为啥调了这么久

    #include<bits/stdc++.h>
    using namespace std;
    #define mo 998244353
    #define N 500010
    #define ll unsigned long long
    #define int long long
    #define pl vector<int>
    int qp(int x,int y){
    	int r=1;
    	for(;y;y>>=1,x=1ll*x*x%mo)
    		if(y&1)r=1ll*r*x%mo;
    	return r;
    }
    int rev[N],v,le,w[N];
    void deb(pl x){
    	for(int i=0;i<x.size();i++)
    		printf("%lld ",x[i]);
    	puts("");
    }
    void init(int n){
    	v=1;
    	le=0;
    	while(v<n)le++,v*=2;
    	for(int i=0;i<v;i++)
    		rev[i]=(rev[i>>1]>>1)|((i&1)<<(le-1));
    	int g=qp(3,(mo-1)/v);
    	w[v/2]=1;
    	for(int i=v/2+1;i<v;i++)
    		w[i]=1ull*w[i-1]*g%mo;
    	for(int i=v/2-1;~i;i--)
    		w[i]=w[i*2];
    }
    void fft(int v,pl &a,int t){
    	static unsigned long long b[N];
    	int s=le-__builtin_ctz(v);
       	for(int i=0;i<v;i++)
       		b[rev[i]>>s]=a[i];
    	int c=0;
    	w[0]=1;
        for(int i=1;i<v;i*=2,c++)
        	for(int r=i*2,j=0;j<v;j+=r)
                for(int k=0;k<i;k++){
                   	int tx=b[j+i+k]*w[k+i]%mo;
                	b[j+i+k]=b[j+k]+mo-tx;
                	b[j+k]+=tx;
                }
        for(int i=0;i<v;i++)
        	a[i]=b[i]%mo;
        if(t==0)return;
        int iv=qp(v,mo-2);
        for(int i=0;i<v;i++)
        	a[i]=1ull*a[i]*iv%mo;
        a.resize(v);
        reverse(a.begin()+1,a.end());
    }
    pl operator *(pl x,pl y){
    	int s=x.size()+y.size()-1;
    	if(x.size()<=20||y.size()<=20){
    		pl r;
    		r.resize(s);
    		for(int i=0;i<x.size();i++)
    			for(int j=0;j<y.size();j++)
    				r[i+j]=(r[i+j]+x[i]*y[j])%mo;
    		return r;
    	}
    	init(s);
    	x.resize(v);
    	y.resize(v);
    	fft(v,x,0);
    	fft(v,y,0);
    	//deb(x);
    	//deb(y);
    	for(int i=0;i<v;i++)
    		x[i]=x[i]*y[i]%mo;
    	fft(v,x,1);
    	x.resize(s);
    	return x;
    }
    void inv(int n,pl &b,pl &a){
    	if(n==1){
    		b[0]=qp(a[0],mo-2);
    		return;
    	}
    	inv((n+1)/2,b,a);
        static pl c;
    	init(n*2);
    	c.resize(v);
    	b.resize(v);
        for(int i=0;i<n;i++)
    		c[i]=a[i];
        fft(v,c,0);
        //deb(c);
    	fft(v,b,0);
    	//deb(b);
        for(int i=0;i<v;i++)
        	b[i]=1ll*(2ll-1ll*c[i]*b[i]%mo+mo)%mo*b[i]%mo;
        //deb(b);
        fft(v,b,1);  
       	b.resize(n);
       	//deb(b);
    }
    void ad(pl &x,pl y,int l){
    	x.resize(max((int)x.size(),(int)y.size()+l));
    	for(int i=0;i<y.size();i++)
    		x[i+l]=(x[i+l]+y[i])%mo;
    }
    pl operator +(pl x,pl y){
    	ad(x,y,0);
    	return x;
    }
    pl iv(pl x){
    	pl y;
    	int n=x.size();
    	y.resize(n);
    	inv(n,y,x);
    	y.resize(n);
    	return y;
    }
    pl operator -(pl x,pl y){
    	int s=max(x.size(),y.size());
    	x.resize(s);
    	y.resize(s);
    	for(int i=0;i<s;i++)
    		x[i]=(x[i]-y[i]+mo)%mo;
    	return x;
    }
    pl qd(pl x){
    	pl y;
    	int n=x.size();
    	y.resize(n-1);
    	//deb(x);
    	for(int i=0;i<n-1;i++)
    		y[i]=x[i+1]*(i+1)%mo;
    	//deb(y);
    	return y;
    }
    pl jf(pl x){
    	int n=x.size();
    	pl y;
    	y.resize(n+1);
    	for(int i=1;i<=n;i++)
    		y[i]=x[i-1]*qp(i,mo-2)%mo;
    	return y;
    }
    pl ln(pl x){
    	int n=x.size();
    	pl y=qd(x),z=iv(x);
    	y=y*z;
    	y=jf(y);
    	y.resize(n);
    	return y;
    }
    char bf[100];
    void wr(int x){
    	if(!x){
    		putchar('0');
    		putchar(' ');
    		return;
    	}
        int ct=0;
        while(x){
            bf[++ct]=x%10;
            x/=10;
        }
        for(int i=ct;i;i--)
            putchar(bf[i]+'0');
        putchar('
    ');
    }
    void gt(int n,pl &y,pl x){
    	if(n==1){
    		y.resize(1);
    		y[0]=1;
    		return;
    	}
    	gt((n+1)/2,y,x);
    	pl z=x,a;
    	z.resize(n);
    	y.resize(n);
    	a.resize(1);
    	a[0]=1;
    	y=y*(a-ln(y)+z);
    	y.resize(n);
    }
    pl ep(pl x){
    	pl y;
    	int n=x.size();
    	gt(n,y,x);
    	return y;
    }
    void put(pl a){
    	for(int i=0;i<a.size();i++)
    		printf("%lld ",a[i]);
    	puts("");
    }
    int n,a[N],q,ii[N],c[N],jc[N],ij[N];
    signed g[N/5+10][400];
    pl f;
    void gt(int m){
    	f.resize(m+1);
    	for(int i=1;i<=m;i++)
    		for(int j=i;j<=m;j+=i)
    			f[j]=(f[j]+c[i]*(mo-ii[j/i]))%mo;
    	f=ep(f);
    }
    int cc(int y,int x){
    	return jc[y]*ij[x]%mo*ij[y-x]%mo;
    }
    int qu(int a,int b){
    	if(a<0)
    		return 0;
    	if(b<400)
    		return g[a][b];
    	else{
    		int ans=0;
    		for(int j=a;j>=0;j-=b)
    			ans=(ans+f[j])%mo;
    		return ans;
    	}
    }
    signed main(){
    	jc[0]=ij[0]=1;
    	for(int i=1;i<N;i++){
    		ii[i]=qp(i,mo-2);
    		jc[i]=jc[i-1]*i%mo;
    	}
    	ij[N-1]=qp(jc[N-1],mo-2);
    	for(int i=N-1;i;i--)
    		ij[i-1]=ij[i]*i%mo;
    	scanf("%lld%lld",&n,&q);
    	int va=1;
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&a[i]);
    		a[i]++;
    		va=va*a[i]%mo;
    	}
    	pl d;
    	d.resize(100010);
    	for(int i=0;i<100010;i++)
    		d[i]=cc(n+i,n);
    	for(int i=1;i<=n;i++)
    		c[a[i]]++;
    	gt(100010);
    	f=f*d;
    	for(int j=1;j<400;j++)
    		for(int i=0;i<100010;i++){
    			if(i>=j)
    				g[i][j]=(g[i-j][j]+f[i])%mo;
    			else
    				g[i][j]=f[i];
    		}
    	for(int i=1;i<=q;i++){
    		int p,x,y,ans=0;
    		scanf("%lld%lld%lld",&p,&x,&y);
    		y--;
    		x++;
    		ans=(ans+qu(y,a[p]))%mo;
    		ans=(ans-qu(y-x,a[p])+mo)%mo;
    		int vv=va*ii[a[p]]%mo*x%mo,vs=vv;
    		vs=(vs-ans+mo)%mo;
    		printf("%lld
    ",vs*qp(vv,mo-2)%mo);
    	}
    }
    
  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14436472.html
Copyright © 2011-2022 走看看