zoukankan      html  css  js  c++  java
  • 【TJOI2019 Day1】简要题解

    T1:

    传送门
    傻逼题,一个裸的矩乘就完了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    const int mod=1e9+7;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    struct mat{
    	int a[26][26];
    	mat(){memset(a,0,sizeof(a));}
    	friend inline mat operator *(cs mat &a,cs mat &b){
    		mat c;
    		for(int i=0;i<26;i++)
    		for(int k=0;k<26;k++)
    		for(int j=0;j<26;j++)
    		Add(c.a[i][j],mul(a.a[i][k],b.a[k][j]));
    		return c;
    	}
    };
    inline mat ksm(mat a,ll b){
    	mat res;
    	for(int i=0;i<26;i++)res.a[i][i]=1;
    	for(;b;b>>=1,a=a*a)if(b&1)res=res*a;
    	return res;
    }
    mat got;
    ll n;
    int res;
    char s[100005];
    int main(){
    	cin>>n;
    	scanf("%s",s+1);
    	for(int i=0;i<26;i++)for(int j=0;j<26;j++)got.a[i][j]=1;
    	for(int i=1,len=strlen(s+1);i<len;i++){
    		got.a[s[i]-'a'][s[i+1]-'a']=0;
    	}
    	got=ksm(got,n-1);
    	for(int i=0;i<26;i++)
    	for(int j=0;j<26;j++)
    	Add(res,got.a[i][j]);
    	cout<<res;
    }
    

    T2:

    传送门
    傻逼题,一个裸的平衡树就完了
    不过fhqtreapfhq-treap很容易TT
    splaysplay会快很多

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define uint unsigned int
    const int mod=1e9+7;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=2000005;
    int n,m;
    uint seed,last=7;
    namespace RAND{
    	typedef unsigned int ui;
    	inline ui Rand() {
    	    seed = seed * 17 + last;
    	    return seed % m + 1;
    	}
    }
    using RAND::Rand;
    namespace treap{
    	int son[N][2],siz[N],key[N],rt,tot;
    	pii val[N];
    	#define lc(u) son[u][0]
    	#define rc(u) son[u][1]
    	int sd=233;
    	inline int rnd(){
    		return sd=int(sd*482711ll%2147483647);
    	}
    	inline void init(){
    		for(int i=1;i<N;i++)key[i]=rnd();	
    	}
    	inline void clear(){
    		rt=tot=0;
    	}
    	inline int newnode(pii k){
    		int u=++tot;siz[u]=1,lc(u)=rc(u)=0,val[u]=k;
    		return u;
    	}
    	inline void pushup(int u){
    		siz[u]=siz[lc(u)]+siz[rc(u)]+1;
    	}
    	inline void split(int r1,int &a,int &b,pii k){
    		if(r1==0){a=b=0;return;}
    		if(val[r1]<=k){
    			a=r1,split(rc(r1),rc(a),b,k);
    		}
    		else b=r1,split(lc(r1),a,lc(b),k);
    		pushup(r1);
    	}
    	inline void merge(int &r1,int a,int b){
    		if(!a||!b){r1=a+b;return;}
    		if(key[a]<key[b]){r1=a,merge(rc(r1),rc(a),b);}
    		else r1=b,merge(lc(r1),a,lc(b));
    		pushup(r1);
    	}
    	inline void insert(pii k){
    		int u=newnode(k),r1,r2;
    		split(rt,r1,r2,k);
    		merge(r1,r1,u);
    		merge(rt,r1,r2);
    	}
    	inline void delet(pii k){
    		int r1,r2,r3;
    		split(rt,r1,r2,pii(k.fi,k.se-1));
    		split(r2,r2,r3,k);
    		merge(r2,lc(r2),rc(r2));
    		merge(r1,r1,r2);
    		merge(rt,r1,r3);
    	}
    	inline int getrk(pii k){
    		int r1,r2;
    		split(rt,r1,r2,pii(k.fi,k.se-1));
    		int res=siz[r1];
    		merge(rt,r1,r2);return res;
    	}
    }
    pii p[N];
    int main(){
    	int T=read();
    	treap::init();
    	while(T--){
    		treap::clear();
    		m=read(),n=read(),seed=read();
    		//for(int i=1;i<=m;i++)treap::insert(p[i]);
    		for(int i=1;i<=n;i++){
    			int x=Rand(),y=Rand();
    			if(p[x].fi)treap::delet(p[x]);
    			p[x].fi--,p[x].se+=y;
    			treap::insert(p[x]);
    			cout<<(last=treap::getrk(p[x]))<<'
    ';
    		}
    		for(int i=1;i<=m;i++)p[i]=pii(0,0);
    	}
    }
    

    T3:

    传送门
    律师函警告

    一个显然的思路是求出至少kk组讨论cxkcxk的方案后容斥
    考虑这kk组人位置的方案数显然是(n3kk){n-3kchoose k}

    然后考虑剩下的怎么放
    对每种人构建EGF:f(x)=i=0akxii!EGF:f(x)=sum_{i=0}^{a-k}frac{x^i}{i!}
    NTTNTT直接乘起来取n4kn-4k次项就是了
    模数很友好

    好像直接暴力卷积都可以过QwQQwQ

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define uint unsigned int
    #define poly vector<int>
    const int mod=998244353,G=3;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){a=add(a,b);}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=1005;
    int fac[N],ifac[N],s[N],g[N][N],f[N],ans[N];
    int n,a,b,c,d,mx;
    int rev[N<<2];
    poly w[14];
    inline void init_w(){
    	cs int C=13;
    	for(int i=1;i<=C;i++)w[i].resize(1<<(i-1));
    	int wn=ksm(G,(mod-1)/(1<<C));
    	w[C][0]=1;
    	for(int i=1;i<=(1<<(C-1));i++)w[C][i]=mul(w[C][i-1],wn);
    	for(int i=C-1;i;i--)
    	for(int j=0;j<(1<<(i-1));j++)
    	w[i][j]=w[i+1][j<<1];
    }
    inline void init_rev(int lim){
    	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
    }
    inline void ntt(poly &f,int lim,int kd){
    	for(int i=0;i<lim;i++)if(i>rev[i])swap(f[i],f[rev[i]]);
    	for(int mid=1,l=1,a0,a1;mid<lim;mid<<=1,l++)
    	for(int i=0;i<lim;i+=(mid<<1))
    	for(int j=0;j<mid;j++)
    	a0=f[i+j],a1=mul(w[l][j],f[i+j+mid]),f[i+j]=add(a0,a1),f[i+j+mid]=dec(a0,a1);
    	if(kd==-1){
    		reverse(f.bg()+1,f.bg()+lim);
    		for(int i=0,inv=Inv(lim);i<lim;i++)Mul(f[i],inv);
    	}
    }
    inline void init(){
    	cs int len=N-5;
    	fac[0]=ifac[0]=1;
    	for(int i=1;i<=len;i++)fac[i]=mul(fac[i-1],i);
    	ifac[len]=Inv(fac[len]);
    	for(int i=len-1;i;i--)ifac[i]=mul(ifac[i+1],i+1);
    }
    inline int C(int n,int m){
    	return n<m?0:mul(fac[n],mul(ifac[m],ifac[n-m]));
    }
    inline int calc(int x){
    	int res=C(n-3*x,x),lim=1;
    	poly A,B,C,D;
    	for(int i=0;i<=a-x;i++)A.pb(ifac[i]);
    	for(int i=0;i<=b-x;i++)B.pb(ifac[i]);
    	for(int i=0;i<=c-x;i++)C.pb(ifac[i]);
    	for(int i=0;i<=d-x;i++)D.pb(ifac[i]);
    	int deg=A.size()+B.size()+C.size()+D.size()-3;
    	while(lim<deg)lim<<=1;
    	init_rev(lim);
    	A.resize(lim),ntt(A,lim,1);
    	B.resize(lim),ntt(B,lim,1);
    	C.resize(lim),ntt(C,lim,1);
    	D.resize(lim),ntt(D,lim,1);
    	for(int i=0;i<lim;i++)A[i]=1ll*A[i]*B[i]%mod*C[i]%mod*D[i]%mod;
    	ntt(A,lim,-1),A.resize(deg);
    	return mul(res,mul(A[n-4*x],fac[n-4*x]));
    }
    int main(){
    	init(),init_w();
    	n=read(),a=read(),b=read(),c=read(),d=read(),mx=min(min(a,b),min(c,d)),mx=min(mx,n/4);
    	for(int i=0;i<=mx;i++){
    		f[i]=calc(i);
    	}
    	int res=0;
    	for(int j=0;j<=mx;j++)
    	if(j&1)Dec(res,f[j]);
    	else Add(res,f[j]);
    	cout<<res;
    }
    

  • 相关阅读:
    durex-word
    闲聊可穿戴设备
    闲聊质数
    一步一步学swift之:自己写Api接口-PHP
    Swift实战-小QQ(第2章):QQ侧滑菜单
    Swift实战-小QQ(第1章):QQ登录界面
    一步一步学习Swift之(一):关于swift与开发环境配置
    objective-c底层: runtime机制
    手把手教你视频直播开发
    多语言本地化开发Localized
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328598.html
Copyright © 2011-2022 走看看