• Code Chef October Challenge 2019题解


    传送门

    (MSV)

    设个阈值搞一搞就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define pb emplace_back
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=1e6+5,L=1e6,S=300;
    int sz[N],cnt[N],x,n,T,res,ret;
    int main(){
    	for(scanf("%d",&T);T;--T){
    		scanf("%d",&n),res=0;
    		fp(i,1,n){
    			scanf("%d",&x);
    			if(x<=S)cmax(res,cnt[x]);
    			else{
    				ret=0;
    				for(R int j=x;j<=L;j+=x)ret+=sz[j];
    				cmax(res,ret);
    			}
    			++sz[x];
    			fp(j,1,min(S,x))if(x%j==0)++cnt[j];
    		}
    		fp(i,1,L)sz[i]=0;
    		fp(i,1,S)cnt[i]=0;
    		printf("%d
    ",res);
    	}
    	return 0;
    }
    

    (B)

    根据总的次数搞一搞就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    const int N=10005;
    ll k,c;int a[N],n,T;
    inline void sl1(){
    	fp(i,0,(n-2)>>1){
    		R int x=a[i],y=a[n-1-i],z=x^y;
    		a[i]=z,a[n-1-i]=x;
    	}
    }
    inline void sl2(){
    	fp(i,0,(n-2)>>1){
    		R int x=a[i],y=a[n-1-i],z=x^y;
    		a[i]=y,a[n-1-i]=z;
    	}
    }
    int main(){
    	for(scanf("%d",&T);T;--T){
    		scanf("%d%lld",&n,&k);
    		fp(i,0,n-1)scanf("%d",&a[i]);
    		c=k/n,k%=n;
    		switch(c%3){
    			case 1:sl1();break;
    			case 2:sl2();break;
    		}
    		if(n&1)a[n>>1]=(c?0:a[n>>1]);
    		fp(i,0,k-1)a[i]=a[i]^a[n-1-i];
    		fp(i,0,n-1)printf("%d ",a[i]);
    		puts("");
    	} 
    	return 0;
    }
    

    (EVEDG)

    如果(m)是偶数全都扔一个集合里

    否则如果有一个点的度数是奇数,那么把这个点单独一个集合,其它的放一起

    如果没有点的度数是奇数,那么随便找一条边,把这条边连的两个点设成不同的颜色,其他所有点为第三个颜色

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=1e5+5;
    int deg[N],n,m,T,u,v,s;
    int main(){
    	for(scanf("%d",&T);T;--T){
    		scanf("%d%d",&n,&m);
    		memset(deg,0,(n+1)<<2);
    		fp(i,1,m)scanf("%d%d",&u,&v),deg[u]^=1,deg[v]^=1;
    		if(m&1^1){
    			puts("1");
    			fp(i,1,n)printf("%d ",1);
    			puts("");
    			continue;
    		}
    		s=0;fp(i,1,n)if(deg[i]&1){s=i;break;}
    		if(s){
    			puts("2");
    			fp(i,1,s-1)printf("%d ",1);
    			printf("%d ",2);
    			fp(i,s+1,n)printf("%d ",1);
    			puts("");
    			continue;
    		}
    		if(u>v)swap(u,v);
    		puts("3");
    		fp(i,1,u-1)printf("%d ",1);
    		printf("%d ",2);
    		fp(i,u+1,v-1)printf("%d ",1);
    		printf("%d ",3);
    		fp(i,v+1,n)printf("%d ",1);
    		puts("");
    		continue;
    	}
    	return 0;
    }
    

    (BACREP)

    不考虑子树问题的话一个修改可以看成在(t-dep[u])的位置放了(k)个,然后询问可以看成在(t-dep[u])的位置有多少个,叶子的话就是做个前缀和

    考虑子树问题的话我们离线,按(dfs)序遍历一遍,进子树时修改,出子树时撤销修改就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fi first
    #define se second
    #define pb emplace_back
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pi;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    inline char getop(){R char ch;while((ch=getc())!='+'&&ch!='?');return ch;}
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R ll x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int N=1e6+55,M=5e5+10;
    struct eg{int v,nx;}e[N<<1];int head[N],tot;
    inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    ll c[N];int n,q;
    inline void chg(R int x,R int y){for(x+=M;x<=q+M;x+=x&-x)c[x]+=y;}
    inline ll query(R int x){R ll res=0;for(x+=M;x;x-=x&-x)res+=c[x];return res;}
    vector<pi>ch[N];vector<int>qr[N];
    ll ans[N];int vq[N],sz[N],dep[N],a[N],cnt;
    void dfs(int u,int fa){
    	dep[u]=dep[fa]+1,sz[u]=0;
    	go(u)if(v!=fa)++sz[u],dfs(v,u);
    }
    void find(int u,int fa){
    	for(auto v:ch[u])chg(v.fi-dep[u],v.se);
    	for(auto v:qr[u])ans[v]=query(v-dep[u]);
    	if(sz[u])for(auto v:qr[u])ans[v]-=query(v-dep[u]-1);
    	go(u)if(v!=fa)find(v,u);
    	for(auto v:ch[u])chg(v.fi-dep[u],-v.se);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),q=read();
    	for(R int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);
    	fp(i,1,n)a[i]=read();
    	dfs(1,0);
    	fp(i,1,n)ch[i].pb(pi(0,a[i]));
    	for(R int i=1,u,x,op;i<=q;++i){
    		op=getop(),u=read();
    		if(op=='+')x=read(),ch[u].pb(pi(i,x));
    			else qr[u].pb(i),vq[i]=1;
    	}
    	find(1,0);
    	fp(i,1,q)if(vq[i])print(ans[i]);
    	return Ot(),0;
    }
    

    (TANDON)

    有种在做提答题的感觉……

    首先鉴于某些边界原因如果(nleq 6)我们直接跑暴力

    然后我们接下来就直接枚举(k)啦!

    • (k=10),只有(0)合法

    • (k=2),最高位为(2,4,6,8),最低位为(0,2,4,6,8),中间可以随便选,那么枚举总位数然后等比数列求和即可,记得最后加上总位数小于(2)的情况

    • (k=4),一个数为(4)的倍数当且仅当后两位是(4)的倍数,那么打个表看一下可以做后两位的数的个数和前两位的数的个数,中间随便选,记得最后加上总位数小于(4)的情况

    • (k=8),一个数为(8)的倍数当且仅当后三位是(8)的倍数,其他同上

    • (k=5),最高位是(5),最低位是(0,5),中间随便选,其余同(k=2)

    • (k=3),发现(3)的倍数反转依然是(3)的倍数,那么答案就是(0)(10^n-1)(3)的倍数的个数

    • (k=9),同(k=3)

    • (k=6),首先要满足(k=2)的情况,其次要满足所有位加起来是(3)的倍数,那么假设现在中间的位数为(i),记(p={10^i-1over 3}),则有中间那几位(p)种选法使和模(3)(1)(2),有(p+1)种选法使和模(3)(0),再根据选择的首位末位加起来模(3)的余数讨论一下就行了

    • (k=7),这个东西啥性质都没有,只能爆算了,设(f[i][j][k])表示考虑到第(i)位,且原数模(7)余数为(j),翻转之后模(7)(k)的方案数,那么(f[n][0][0])就是答案了

    暴力的代码如下

    int calc(){
    	memset(f,0,sizeof(f));
    	f[0][0][0]=1,t=0,p=1;
    	fp(i,0,n-1){
    		memset(f[t^1],0,sizeof(f[t^1]));
    		fp(j,0,6)fp(k,0,6)if(f[t][j][k])
    			fp(l,0,9)upd(f[t^1][(j+l*p)%7][(k*10+l)%7],f[t][j][k]);
    		p=p*10%7,t^=1;
    	}
    	return f[t][0][0];
    }
    

    事实上这个也可以扩展到(k)为其它的情况,不过仔细思考之后你可以惊喜的发现除了(k=3,7,9)之外其它全都是错的

    既然已经写出暴力了用矩乘优化一下就行了

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define gg(x) printf("%d
    ",x);break;
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int P=1e9+7,inv3=333333336;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    int kkk(R int x,R int y){
    	//求1+x+x^2+...+x^y 
    	R int res=1,d=1;
    	for(;y;y>>=1,d=mul(d,x+1),x=mul(x,x))(y&1)?res=add(mul(res,x),d):0;
    	return res;
    }
    inline int rev(R int x){R int res=0;while(x)res=res*10+x%10,x/=10;return res;}
    int r[1000005];
    const int N=55;
    struct Matrix{
    	int a[N][N];
    	inline Matrix(){memset(a,0,sizeof(a));}
    	inline int* operator [](const int &x){return a[x];}
    	inline Matrix operator *(Matrix b){
    		Matrix c;
    		fp(i,1,49)fp(k,1,49)fp(j,1,49)upd(c[i][j],mul(a[i][k],b[k][j]));
    		return c;
    	}
    }mi[15],bin[35];
    int id[15][15];
    void init(){
    	R int p=1,tot=0;
    	fp(i,0,6)fp(j,0,6)id[i][j]=++tot;
    	fp(i,1,6){
    		fp(j,0,6)fp(k,0,6)fp(l,0,9)++mi[i][id[j][k]][id[(j+l*p)%7][(k*10+l)%7]];
    		p=p*10%7;
    	}
    	fp(i,1,49)bin[0][i][i]=mi[0][i][i]=1;
    	fp(i,2,6)mi[i]=mi[i-1]*mi[i];
    	bin[1]=mi[6];
    	fp(i,2,30)bin[i]=bin[i-1]*bin[i-1];
    }
    int f[2][N][N],bas,t,p,T,n;
    Matrix ksm(R int y){
    	Matrix res=bin[0];
    	for(R int i=1;y;y>>=1,++i)if(y&1)res=res*bin[i];
    	return res;
    }
    int calc(){
    	Matrix ret;ret[1][1]=1;
    	ret=ret*ksm(n/6),ret=ret*mi[n%6];
    	return ret[1][1];
    }
    inline int brute(){
    	R int res=1,p=ksm(10,n);
    	for(R int i=bas;i<p;i+=bas)if(r[i]%bas==0)++res;
    	return res;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	fp(i,1,1e6)r[i]=rev(i);
    	init();
    	for(scanf("%d",&T);T;--T){
    		scanf("%d%d",&n,&bas);
    		if(n<=6){printf("%d
    ",brute());continue;}
    		switch(bas){
    			case 10:gg(1);
    			case 2:gg(add(mul(20,kkk(10,n-2)),5));
    			case 5:gg(add(mul(2,kkk(10,n-2)),2));
    			case 4:gg(add(mul(500,kkk(10,n-4)),59));
    			case 8:gg(add(mul(12500,kkk(10,n-6)),1392));
    			case 3:gg(mul(3,kkk(10,n-1))+1);
    			case 9:gg(kkk(10,n-1)+1);
    			case 6:{
    				R int p=kkk(10,n-2);
    				R int res=add(mul(14,dec(p,n-1)),mul(6,add(p,mul(2,n-1))));
    				printf("%d
    ",mul(res,inv3)+2);
    				break;
    			}
    			case 7:gg(calc());
    		}
    	}
    	return 0;
    }
    

    (JIIT)

    生成函数差的一比……所以还是看(jz)姐姐说的吧

    然后我就卡了一个晚上的常……(zyy)聚聚似乎随便过,不知道他写了个什么……

    //quming
    #include<bits/stdc++.h>
    #define R register
    #define fi first
    #define se second
    #define pb emplace_back
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    typedef vector<int> poly;
    typedef long long ll;
    const int P=998244353,inv2=499122177;
    inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R ll y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
    	return res;
    }
    const int N=5005;
    poly e,eg,ef,bf[N],bg[N];int bin[N],ibin[N],fac[N],ifac[N],n,m,T,z,res;
    ll q;int np[N],sr[N],sc[N];
    poly operator *(const poly &a,const poly &b){
    	int n=a.size(),m=b.size(),dn=n-1,dm=m-1,dc=dn+dm;
    	poly c(dc+1);
    	fp(i,0,n-1)fp(j,0,m-1)upd(c[i+j],mul(a[i],b[j]));
    	return c;
    }
    poly Dg(const poly &a){
    	int n=a.size(),dn=n-1,dc=dn-1,t;
    	poly c(dc+1),d(a);
    	for(R int i=dn,j=dc;i;--i,--j){
    		t=c[j]=d[i];
    		d[i]=dec(d[i],t),d[i-1]=dec(d[i-1],t);
    	}
    	return c;
    }
    inline int C(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
    void init(){ 
    	/*
    		多项式第i项的系数表示e^{ix}的系数 
    		又因为所有形如e^x+e^{-x}的幂次的形式里只有一半的系数不为0
    		所以多项式里只考虑那些系数不为0的项了 
    	*/
    	e.resize(1),e[0]=1;
    	ef.resize(2),ef[0]=P-1,ef[1]=1;
    	eg.resize(2),eg[0]=1,eg[1]=1;
    	bf[0]=bg[0]=e;
    	fp(i,1,2000)bf[i]=bf[i-1]*ef;
    	fp(i,1,2000)bg[i]=bg[i-1]*eg;
    	fac[0]=ifac[0]=1;fp(i,1,2000)fac[i]=mul(fac[i-1],i);
    	ifac[2000]=ksm(fac[2000],P-2);fd(i,2000-1,1)ifac[i]=mul(ifac[i+1],i+1);
    	bin[0]=ibin[0]=1;
    	fp(i,1,2000)bin[i]=mul(bin[i-1],2),ibin[i]=mul(ibin[i-1],inv2);
    }
    inline int calc(const poly &A,R int p){
    	R int ret=0;
    	for(R int i=0,j=-p;j<0;++i,j+=2)upd(ret,mul(A[i],q&1?P-np[-j]:np[-j]));
    	for(R int i=p,j=p;j>0;--i,j-=2)upd(ret,mul(A[i],np[j]));
    	return ret;
    }
    void calc(int n,int *s){
    	poly c=bg[n];
    	fp(i,0,n)c[i]=mul(c[i],ibin[n]);
    	s[0]=calc(c,n);
    	fp(i,1,n)c=Dg(c),c=c*ef,s[i]=mul(C(n,i),calc(c,n)); 
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	init();
    	for(scanf("%d",&T);T;--T){
    		scanf("%d%d%lld%d",&n,&m,&q,&z),res=0;
    		np[0]=1;fp(i,1,max(n,m))np[i]=ksm(i,q);
    		calc(n,sc),calc(m,sr);
    		fp(i,0,n)fp(j,0,m)if(i*(m-j)+j*(n-i)==z)
    			upd(res,mul(sc[i],sr[j]));
    		printf("%d
    ",res);
    	}
    	return 0;
    }
    

    (CNNCT2)

    裸的拟阵交,具体可以看18年论文《浅谈拟阵的一些拓展及其应用 杨乾澜》

    //quming
    #include<bits/stdc++.h>
    #define R register
    #pragma GCC optimize(3)
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    using namespace std;
    const int N=305,M=N*N;
    struct eg{int v,nx;}e[M];int head[N],tot;
    inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
    struct EG{int u,v;}f[N],g[N];
    int fa[N],ga[N],st[N],vis[N],va[N],vb[N],vc[N],fr[N],ok[N],q[N];
    int n,m,T,top;
    inline int find(R int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    inline int gind(R int x){return ga[x]==x?x:ga[x]=gind(ga[x]);}
    bool bfs(){
    	R int h=1,t=0,u;
    	fp(i,1,m){
    		ok[i]=vc[i]=fr[i]=0;
    		if(va[i])q[++t]=i,ok[i]=1;
    	}
    	while(h<=t){
    		u=q[h++];if(vb[u])break;
    		go(u)if(!ok[v])q[++t]=v,fr[v]=u,ok[v]=1;
    	}
    	if(!vb[u])return false;
    	for(;u;u=fr[u])vc[u]=1;
    	return true;
    }
    void solve(){
    	top=0;
    	fp(i,1,m)vis[i]=0;
    	while(true){
    		memset(head,0,(m+1)<<2),tot=0;
    		fp(k,1,top){
    			fp(i,1,n)fa[i]=ga[i]=i;
    			fp(i,1,top)if(i!=k){
    				fa[find(f[st[i]].u)]=find(f[st[i]].v);
    				ga[gind(g[st[i]].u)]=gind(g[st[i]].v);
    			}
    			fp(i,1,m)if(!vis[i]){
    				if(find(f[i].u)!=find(f[i].v))add(st[k],i);
    				if(gind(g[i].u)!=gind(g[i].v))add(i,st[k]);
    			}
    		}
    		fp(i,1,m)va[i]=vb[i]=vc[i]=0;
    		fp(i,1,n)fa[i]=ga[i]=i;
    		fp(i,1,top){
    			fa[find(f[st[i]].u)]=find(f[st[i]].v);
    			ga[gind(g[st[i]].u)]=gind(g[st[i]].v);
    		}
    		fp(i,1,m)if(!vis[i]){
    			if(find(f[i].u)!=find(f[i].v))va[i]=1;
    			if(gind(g[i].u)!=gind(g[i].v))vb[i]=1;
    		}
    		if(!bfs())break;
    		top=0;
    		fp(i,1,m)if(vis[i]^vc[i])st[++top]=i;
    		fp(i,1,m)vis[i]=0;fp(i,1,top)vis[st[i]]=1;
    	}
    	printf("%d
    ",((n-1)<<1)-top);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	for(scanf("%d",&T);T;--T){
    		scanf("%d%d",&n,&m);
    		fp(i,1,m)scanf("%d%d",&f[i].u,&f[i].v);
    		fp(i,1,m)scanf("%d%d",&g[i].u,&g[i].v);
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    Amazon Hiring Campus 2013
    Java历史
    vue配置环境踩坑
    ES6 第十八节 模块化操作
    ES6 第十七节 class类的使用
    ES6 第十六节 promise对象的使用
    ES6 第十五节 用proxy进行预处理
    ES6 第十四节 map数据结构
    ES6 第十三节 Set和WeakSet数据结构
    ES6 第十二节 Symbol在对象中的作用
  • 原文地址:https://www.cnblogs.com/yuanquming/p/11622925.html
Copyright © 2020-2023  润新知