模板——多项式

取模下的运算(模数确定)

点击查看代码

void inc(int& x,int y){
    x+=y;
    if(x>=P) x-=P;
    if(x<0) x+=P;
}
int sum(int x,int y){
    x+=y;
    if(x>=P) x-=P;
    if(x<0) x+=P;
    return x;
}
void mul(int& x,int y){
    x=1ll*x*y%P;
}
int prd(int x,int y){
    return 1ll*x*y%P;
}

inline int fpw(int a,int x){
    int s=1;
    for(;x;x>>=1,a=prd(a,a)) if(x&1) s=prd(s,a);
    return s;
}

组合数预处理

点击查看代码
const int N=4e5+5;
int P;
inline int fpw(int a,int x){
    int s=1;
    for(;x;x>>=1,a=1ll*a*a%P) if(x&1) s=1ll*s*a%P;
    return s;
}
int rv[N],iv[N],fc[N],fv[N],pw[N];
void init(int n){
	fc[0]=pw[0]=1;
    for(int i=1;i<n;i++) iv[i]=fpw(i,P-2),fc[i]=1ll*fc[i-1]*i%P,pw[i]=1ll*pw[i-1]*2%P;
    fv[n-1]=fpw(fc[n-1],P-2);
    for(int i=n-2;~i;i--) fv[i]=1ll*fv[i+1]*(i+1)%P;
}
int C(int n,int m){
	if(m<0 || m>n) return 0;
	return 1ll*fc[n]*fv[m]%P*fv[n-m]%P;
}

多项式乘法+求逆+开根+Ln+Exp

(因为一些奇特的原因,预处理得开到四倍)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=(1<<20)+5,P=998244353,G[2]={3,(P+1)/3};
inline int fpw(int a,int x){
    int s=1;
    for(;x;x>>=1,a=1ll*a*a%P) if(x&1) s=1ll*s*a%P;
    return s;
}
int rv[N],gp[2][N],iv[N],fc[N],fv[N];
void init(int n){
	fc[0]=1;
    for(int i=1;i<n;i++) iv[i]=fpw(i,P-2),fc[i]=1ll*fc[i-1]*i%P;
    fv[n-1]=fpw(fc[n-1],P-2);
    for(int i=n-2;~i;i--) fv[i]=1ll*fv[i+1]*(i+1)%P;
    for(int p=0;p<2;p++){
        for(int i=1;i<n;i<<=1){
            gp[p][i]=1;
            int t=fpw(G[p],(P-1)/(i<<1));
            for(int j=i+1;j<(i<<1);j++) gp[p][j]=1ll*gp[p][j-1]*t%P;
        }
    }
}
//cnt:f[0]-f[n-1]
void print(char name[],int n,int* a){
	printf("%s n=%d\n",name,n);
	for(int i=0;i<n;i++) cout<<a[i]<<" "; puts(""); 
}
inline void dft(int* a,int n,int p){
    for(int i=0;i<n;i++) if(i<rv[i]) swap(a[i],a[rv[i]]);
    for(int i=1;i<n;i<<=1){
        for(int j=0;j<n;j+=(i<<1)){
            for(int k=0;k<i;k++){
                int &A=a[i+j+k],&B=a[j+k],t=1ll*gp[p][i+k]*A%P;
                A=B-t; if(A<0) A+=P;
                B=B+t; if(B>=P) B-=P;
            }
        }
    }
    if(p) for(int i=0;i<n;i++) a[i]=1ll*a[i]*iv[n]%P;
}
inline int Rev(int m){
    int p=0,n=1;
    while(n<m) n<<=1,p++;
    for(int i=0;i<n;i++) rv[i]=(rv[i>>1]>>1)|((i&1)<<(p-1));
    return n;
}
inline void poly_mul(int m,int* A,int* B,int* C){
    int n=Rev(m);
    dft(A,n,0); dft(B,n,0);
    for(int i=0;i<n;i++) C[i]=1ll*A[i]*B[i]%P;
    dft(C,n,1);
    fill(C+m,C+n,0);
}
//C=A*B m:需要C的0~(m-1)项,m~(n-1)为空
int C[N],D[N];
inline void poly_inv(int m,int *a, int *b) {
    if(m==1){
        b[0]=fpw(a[0],P-2);
        return;
    }
    poly_inv((m + 1)>>1,a,b);
    int n=Rev(m<<1);
    copy(a,a+m,C);
    fill(C+m,C+n,0);
    dft(b,n,0); dft(C,n,0);
    for(int i=0;i<n;i++) b[i]=1ll*b[i]*(P+2-1ll*b[i]*C[i]%P)%P;
    dft(b,n,1);
    fill(b+m,b+n,0);
}
//a*b=1,给定a的0~(m-1)项,返回b的0~(m-1)项
//需要保证初始b为空!
inline void poly_sqrt(int m,int* a,int* b){
	if(m==1){
		b[0]=1;
		return;
	}
	poly_sqrt((m+1)>>1,a,b);
	poly_inv(m,b,D);
	int n=Rev(m<<1);
	copy(a,a+m,C);
	fill(C+m,C+n,0);
    dft(C,n,0); dft(D,n,0);
    for(int i=0;i<n;i++) C[i]=1ll*D[i]%P*C[i]%P;
    dft(C,n,1);
    for(int i=0;i<n;i++) b[i]=1ll*(P+1)/2*(b[i]+C[i])%P;
    fill(b+m,b+n,0);
    fill(D,D+n,0);
}
//b*b=a,给定a的0~(m-1)项,返回b的0~(m-1)项
//需要保证初始b为空!
inline void poly_Ln(int m,int* a,int* b){
	poly_inv(m,a,b);
	for(int i=0;i<m-1;i++) C[i]=1ll*a[i+1]*(i+1)%P; C[m-1]=0;
    int n=Rev(m<<1);
    fill(C+m,C+n,0);
    dft(C,n,0); dft(b,n,0);
    for(int i=0;i<n;i++) b[i]=1ll*C[i]*b[i]%P;
    dft(b,n,1);
	for(int i=m-1;i;i--) b[i]=1ll*b[i-1]*iv[i]%P; b[0]=0;
	fill(b+m,b+n,0);
}
//b=Ln(a),给定a的0~(m-1)项,返回b的0~(m-1)项
//需要保证初始b为空!
inline void poly_Exp(int m,int* a,int* b){
	if(m==1){
		b[0]=1;
		return;
	}
	poly_Exp((m+1)>>1,a,b);
	poly_Ln(m,b,D);
	for(int i=0;i<m;i++) D[i]=(P+a[i]-D[i]+(i==0))%P;
	int n=Rev(m<<1);
    dft(b,n,0); dft(D,n,0);
    for(int i=0;i<n;i++) b[i]=1ll*b[i]*D[i]%P;
    dft(b,n,1);
    fill(b+m,b+n,0);
    fill(D,D+n,0);
}
//b=Exp(a),给定a的0~(m-1)项,返回b的0~(m-1)项
//需要保证初始b为空!
int main(){
	return 0;
}

FWT

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void fwt(ll* a,int n,int op){
	for(int i=1;i<n;i<<=1)
		for(int p=(i<<1),j=0;j<n;j+=p)
			for(int k=0;k<i;++k){
				ll x=a[j+k],y=a[i+j+k];
				a[j+k]=x+y; a[i+j+k]=x-y;
				if(op==-1) a[j+k]/=2,a[i+j+k]/=2;
			}
}
const int N=(1<<20);
int n,m,a[N];
ll k,A[N];
char ch[N];
int main()
{
	//srand(time(0));
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	//int T; cin>>T; while(T--) work();
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++){
		scanf("%s",ch);
		for(int j=0;j<m;j++) a[i]+=(1<<j)*(ch[j]-'A');
		A[a[i]]++;
	}
	fwt(A,(1<<m),1);
	for(int i=0;i<(1<<m);i++) A[i]*=A[i];
	fwt(A,(1<<m),-1);
	A[0]-=n; //cout<<A[0]<<endl;
	for(int i=0;i<(1<<m);i++) A[i]>>=1;//cout<<A[i]<<" "; puts("");
	for(int i=1;i<=m;i++){
		for(int s=0;s<(1<<(m-i));s++){
			for(int t=0;t<(1<<(i-1));t++)
				A[(s<<i)+(1<<(i-1))+t]+=A[(s<<i)+t];
		}
	}
	int s=0;
	for(int i=0;i<(1<<m);i++) if(A[i]<=(1ll*n*(n-1)/2-k)) s++;
	cout<<s<<endl;
	return 0;
posted @   sz[sz]  阅读(18)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示