• Atcoder Tenka1 Programmer Contest 2019题解


    传送门

    (C Stones)

    最后肯定形如左边一段白+右边一段黑,枚举一下中间的断点,预处理一下前缀和就可以了

    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),read(s),res=0x3f3f3f3f;
    	fp(i,1,n){
    		sum[i][0]=sum[i-1][0],sum[i][1]=sum[i-1][1];
    		++sum[i][s[i]=='#'];
    	}
    	fp(i,0,n)cmin(res,sum[i][1]+sum[n][0]-sum[i][0]);
    	printf("%d
    ",res);
    	return 0;
    }
    

    (D Three Colors)

    首先根据容斥原理,用三种颜色染(n)个物品,且每种颜色都有的方案数是(3^n-3 imes 2^n+3)

    然后我们考虑怎么减去不合法的方案数。不合法的方案一定有一份的和大于等于总和的({1over 2}),我们设(f_{i,j})表示考虑前(i)个数,选的个数总和为(j),且剩下不选的数分为(0/1)的方案数,(g_{i,j})表示剩下不选的数全都设为(0)的方案数,那么不合法的染色方案就是(sum (f_{n,i}-2 imes g_{n,i}) imes 3)。直接转移就是

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inline __inline__ __attribute__((always_inline))
    #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)
    using namespace std;
    const int N=305,P=998244353;
    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 f[2][N*N],g[2][N*N],a[N],n,res,t,sum;
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d",&n);
    	f[0][0]=1,g[0][0]=2,t=0;
    	fp(i,1,n){
    		scanf("%d",&a[i]);
    		memset(f[t^1],0,sizeof(f[t^1]));
    		memset(g[t^1],0,sizeof(g[t^1]));
    		fp(j,0,sum)if(f[t][j]||g[t][j]){
    			upd(f[t^1][j],mul(2,f[t][j]));
    			upd(g[t^1][j],g[t][j]);
    			upd(f[t^1][j+a[i]],f[t][j]);
    			upd(g[t^1][j+a[i]],g[t][j]);
    		}
    		sum+=a[i],t^=1;
    	}
    	fp(i,(sum+1)>>1,sum-1)res=add(res,dec(f[t][i],g[t][i]));
    	res=mul(res,3),res=P-res;
    	res=add(res,ksm(3,n)),res=dec(res,mul(3,ksm(2,n))),res=add(res,3);
    	printf("%d
    ",res);
    	return 0;
    }
    

    (E Polynomial Divisors)

    首先先对所有系数的(gcd)分解质因子,那么这些质因子显然可以

    对于剩下的,若(p)是一个可行的答案,当且仅当(F(x)equiv x^p-xpmod{p})

    证明:因为(p)是一个可行的答案,所以当(x=0,1,2,...,p-1)时,(F(x))恒为(0),所以(F(x)equiv 0pmod{p})的根为(0,1,...,p-1),根据费马小定理,(x^p-xequiv 0pmod{p})的根也是这些。因为(Z_p)是唯一分解整环,所以必有(F(x)equiv x^p-xpmod{p})

    那么我们只要对于所有(leq n)的质数检验一下就好了。简单来说就是计算(F(n)mod (x^p+x))是否为(0)。直接暴力取模就可以了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inline __inline__ __attribute__((always_inline))
    #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)
    using namespace std;
    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;
    }
    const int N=1e5+5;
    bitset<N>vis;int p[N],A[N],st[N],top,n,m,g;
    void init(int n=N-5){
    	fp(i,2,n){
    		if(!vis[i])p[++m]=i;
    		for(R int j=1;j<=m&&i*p[j]<=n;++j){
    			vis[i*p[j]]=1;
    			if(i%p[j]==0)break;
    		}
    	}
    }
    void solve(int x){
    	for(R int i=1;p[i]*p[i]<=x;++i)if(x%p[i]==0){
    		st[++top]=p[i];
    		while(x%p[i]==0)x/=p[i];
    	}
    	if(x!=1)st[++top]=x;
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),init();
    	fd(i,n,0)A[i]=read(),g=__gcd(g,A[i]);
    	solve(abs(g));
    	for(R int i=1;p[i]<=n;++i)if(A[0]%p[i]==0){
    		bool flag=1;
    		fp(j,1,p[i]-1){
    			int res=0;
    			for(R int k=j;k<=n;k+=p[i]-1)(res+=A[k])%=p[i];
    			if(res){flag=0;break;}
    		}
    		if(flag)st[++top]=p[i];
    	}
    	sort(st+1,st+1+top),top=unique(st+1,st+1+top)-st-1;
    	fp(i,1,top)printf("%d
    ",st[i]);
    	return 0;
    }
    

    (F Banned X)

    首先我们先计算出选(i)个数,全为(1/2),且没有连续子串和为(x)的方案数。然后对于每一个(i),用组合数计算出插入(0)的方案就行了

    然后我们枚举选的(i)个数的和(s),记方案数为(f_{i,s}),这可以(O(n^2))直接用背包预处理出来。如果(s<x),那么显然选的时候不会有问题,直接加上(f_{i,s})就好了

    如果(sgeq x),那么一定存在一个位置(k),使得从第(1)个位置到第(k)个位置的和是(x-1)(因为我们选的树数最大只能是(2)),那么第(k+1)个数肯定只能选(2),同理第(1)个数也只能选(2)。于是此时整个数列的形式一定是

    前面(a)(2),后面(a)(2),中间随意。如果(2a<x-1),那么中间那堆的和肯定是(x-1-2a),否则的话,只有当(x)为奇数且所有数都为(2)时,才有贡献

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inline __inline__ __attribute__((always_inline))
    #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)
    using namespace std;
    const int N=3005,P=998244353;
    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 mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int f[N][N<<1],c[N],inv[N],x,n,res;
    int main(){
    //	freopen("testdata.in","r",stdin);
    	scanf("%d%d",&n,&x),res=1;
    	inv[0]=inv[1]=1;fp(i,2,n)inv[i]=mul(P-P/i,inv[P%i]);
    	c[0]=1;fp(i,1,n)c[i]=1ll*c[i-1]*inv[i]%P*(n-i+1)%P;
    	f[0][0]=1;fp(i,0,n-1)fp(j,0,i<<1)upd(f[i+1][j+2],f[i][j]),upd(f[i+1][j+1],f[i][j]);
    	fp(i,1,n){
    		int s=0;
    		fp(j,0,x-1)upd(s,f[i][j]);
    		for(R int j=x+1;j<=(i<<1);j+=2)if(j>=i){
    			int p=i-(j-x+1),q=x-1-(j-x+1);
    			if(j>=x*2)upd(s,j==(i<<1)?x&1:0);
    				else upd(s,p>=0&&q>=0?f[p][q]:0);
    		}
    		upd(res,mul(s,c[i]));
    	}
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    MySQL日期函数与日期转换格式化函数大全
    外设驱动库开发笔记19:BMP280压力温度传感器驱动
    外设驱动库开发笔记18:MS5837压力变送器驱动
    通讯接口应用笔记1:RS485通讯上下拉电阻的选择
    外设驱动库开发笔记17:MS5803压力变送器驱动
    外设驱动库开发笔记16:MS5536C压力变送器驱动
    Elasticserach学习笔记之Elasticsearch查询慢和集群慢查询日志配置
    Linux学习笔记之curl模拟get/post/delete/put请求
    ELK学习笔记之elasticsearch中 refresh 和flush区别
    Prometheus学习笔记之Prometheus是如何定义告警级别的
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10744527.html
Copyright © 2020-2023  润新知