zoukankan      html  css  js  c++  java
  • 【CodeForces】 Educational Codeforces Round 94

    好久没来更新博客了,正好有空,总结一下 CF 1400 这场比赛。

    ABCDE pp,B fst,rating+48

    A. String Similarity

    非常简单的构造题。(w) 的第 (i) 位填上 (s) 的第 (2i+1) 位即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1000009;
    
    int n,m,a[N];
    char c[50];
    
    int main() {
    	int T; scanf("%d",&T);
    	while(T--) {
    		scanf("%d",&n);
    		scanf("%s",c+1);
    		for(int i=1;i<=n;i++) putchar(c[i+i-1]);
    		putchar('
    ');
    	}
    	return 0;
    }
    

    B. RPG Protagonist

    我 FST 的一道题目。原因是没开 long long /kk

    感觉是 ABCD 中最难的一道题目。枚举带的剑的个数,然后贪心去做。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e5+9;
    
    int n,m,p,f,cs,cw,s,w,ans;
    
    int a[N],b[N];
    
    signed main() {
    	int T; scanf("%lld",&T);
    	while(T--) {
    		scanf("%lld%lld%lld%lld%lld%lld",&p,&f,&cs,&cw,&s,&w);
    		if(w<s) swap(s,w), swap(cs,cw);
    		ans=0;
    		for(int i=0;i<=cs;i++) {
    			int sum=0;
    			int rest_s=cs-i, rest_w=cw;
    			if(i*s>p) sum+=p/s;
    			else {
    				p-=i*s;
    				if(p/w<=rest_w) rest_w-=p/w, sum+=p/w;
    				else sum+=rest_w, rest_w=0;
    				sum+=i, p+=i*s;
    			}
    			if(rest_s*s>f) sum+=f/s;
    			else {
    				f-=rest_s*s;
    				if(f/w<=rest_w) rest_w-=f/w, sum+=f/w;
    				else sum+=rest_w, rest_w=0;
    				sum+=rest_s, f+=rest_s*s;
    			}
    			ans=max(ans,sum);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    C. Binary String Reconstruction

    还是小清新构造题。先把那些 0 给安排好(可以确定两个位置),其他位置全部填上 1。判断一下是否可行即可。

    比赛的时候 WA2 了 2 次,原因应该是判断是否可行的 if 里面出了问题。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+9;
    
    int n,x,a[N];
    char c[N],w[N];
    
    int main() {
    	int T; scanf("%d",&T);
    	while(T--) {
    		scanf("%s%d",c+1,&x);
    		n=strlen(c+1);
    		for(int i=1;i<=n;i++) w[i]='a';
    		for(int i=1;i<=n;i++)
    			if(c[i]=='0') w[max(i-x,0)]='0', w[min(i+x,n+1)]='0';
    		bool flag=0;
    		for(int i=1;i<=n;i++)
    			if(c[i]=='1') {
    				if((i-x<=0||w[i-x]=='0')&&(i+x>n||w[i+x]=='0'))
    					flag=1;
    			}
    		if(flag) {puts("-1");continue;}
    		for(int i=1;i<=n;i++) if(w[i]=='a') w[i]='1';
    		for(int i=1;i<=n;i++) putchar(w[i]);
    		puts("");
    	}
    	return 0;
    }
    

    D. Zigzags

    数数题,但是不用用到任何的数据结构。可以用预计算解决。设

    [f(i,j)=sum_{kle j} [a_i=a_k]\ g(i,j)=sum_{kge j} [a_i=a_k] ]

    可以增量式统计。

    [ans=sum_{k=3}^{n-1}sum_{j=2}^{k-1} f(k,j-1)g(j,k+1) ]

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=3009;
    
    int n,m,a[N],f[N][N],g[N][N],ans;
    
    signed main() {
    	int T; scanf("%lld",&T);
    	while(T--) {
    		scanf("%lld",&n);
    		for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    		ans=0;
    		for(int i=1;i<=n;i++) {
    			for(int j=1;j<=n;j++) f[i][j]=f[i][j-1]+(a[i]==a[j]);
    			for(int j=n;j>=1;j--) g[i][j]=g[i][j+1]+(a[i]==a[j]);
    		}
    		for(int k=3;k<n;k++)
    			for(int j=2;j<k;j++)
    				ans+=f[k][j-1]*g[j][k+1];
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

    E. Clear the Multiset

    重题啊……

    贪心的考虑,对于一个区间,要么操作(最小的数)次操作一,要么操作 (r-l+1) 次操作二,递归处理。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=5009;
    
    int n,a[N];
    
    int dp(int l,int r,int ret=0) {
    	if(l>r) return 0;
    	if(l==r) return min(1ll,a[l]);
    	int min_a=0x3f3f3f3f3f3f3f3f;
    	for(int i=l;i<=r;i++) min_a=min(min_a,a[i]);
    	ret+=min_a;
    	for(int i=l;i<=r;i++) a[i]-=min_a;
    	int last_zero=l-1;
    	for(int i=l;i<=r;i++) if(!a[i])
    		ret+=dp(last_zero+1,i-1), last_zero=i;
    	ret+=dp(last_zero+1,r);
    	return min(ret,r-l+1);
    }
    
    signed main() {
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	printf("%lld",dp(1,n));
    	return 0;
    }
    

    G. Mercenaries

    先考虑没有互相讨厌的情况。我们枚举选多少个雇佣兵。设 (p_i) 表示可以接受有 (i) 个雇佣兵的人数,则 (ans=sumlimits_i binom{p_i}{i})

    然后考虑有互相讨厌的情况。考虑大力容斥。枚举哪些冲突发生了(用状压枚举子集的方法),然后这里面的人都要被选中,设这些人的人数为 (k)。设这些一定要被选中的人的 ([l,r]) 的交集为 ([L,R]),则这部分对答案的贡献是

    [sum_{i=L}^{R} dbinom {p_i-k}{i-k} ]

    这个 (sum) 可以前缀和预计算。复杂度 (O(nm+m2^m))

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=3e5+9, M=29, mod=998244353;
    
    int n,m,l[N],r[N],u[N],v[N];
    
    int fac[N],inv[N],ifac[N];
    void pre() {
    	inv[0]=inv[1]=fac[0]=ifac[0]=1;
    	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
    	for(int i=2;i<=n;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    	for(int i=1;i<=n;i++) ifac[i]=ifac[i-1]*inv[i]%mod;
    }
    int C(int x,int y) {
    	if(x<0||y<0||x<y) return 0;
    	else return fac[x]*ifac[y]%mod*ifac[x-y]%mod;
    }
    
    int cf[N],p[N],s[N][49];
    void cal_p() {
    	for(int i=1;i<=n;i++) cf[l[i]]++, cf[r[i]+1]--;
    	int ssum=0;
    	for(int i=1;i<=n;i++) ssum+=cf[i], p[i]=ssum;
    	for(int j=0;j<=2*m;j++) for(int i=1;i<=n;i++) {
    		s[i][j]=(s[i-1][j]+C(p[i]-j,i-j))%mod;
    	}
    }
    
    struct hset {
    	bool vst[N];
    	int ar[N], size;
    	void clear() {
    		for(int i=1;i<=size;i++) vst[ar[i]]=0;
    		size=0;
    	}
    	void add(int x) {if(!vst[x]) ar[++size]=x, vst[x]=1;}
    }st;
    
    #define bit(S,i) (bool)((1<<i-1)&S)
    int ans;
    void in_ex() {
    	for(int S=0;S<(1<<m);S++) {
    		int L=1, R=n, pop=0;
    		for(int j=1;j<=m;j++) if(bit(S,j)) {
    			L=max(L,l[u[j]]), R=min(R,r[u[j]]), st.add(u[j]);
    			L=max(L,l[v[j]]), R=min(R,r[v[j]]), st.add(v[j]);
    			pop++;
    		}
    		if(L>R) {st.clear();continue;}
    		int res=(s[R][st.size]-s[L-1][st.size]+mod)%mod;
    		ans=(ans+res*(pop&1 ? -1 : 1)+mod)%mod;
    		st.clear();
    	}
    }
    
    signed main() {
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%lld%lld",&l[i],&r[i]);
    	for(int i=1;i<=m;i++) scanf("%lld%lld",&u[i],&v[i]);
    	pre();
    	cal_p();
    	in_ex();
    	printf("%lld",(ans+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    紫书 习题2-4 子序列的和
    紫书 习题2-3 倒三角形
    HDU 1013 Digital Roots(字符串,大数,九余数定理)
    HDU 1308 What Day Is It?(模拟,日期)
    ACM数论-欧几里得与拓展欧几里得算法
    今日计划
    UVA 10340 All in All(字符串,朴素匹配)
    ACM-字符串
    Codeforces Round #424 B. Keyboard Layouts(字符串,匹配,map)
    Codeforces Round #424 A(模拟)
  • 原文地址:https://www.cnblogs.com/TetrisCandy/p/cf-1400.html
Copyright © 2011-2022 走看看