• Codeforces Round #670 (Div. 2)


    CF1406A Subset Mex

    洛谷传送门
    CF1406A


    分析

    从小到大考虑每一个数的出现次数,最小未出现的数就是A的mex值,
    然后将A选完的数删掉一个接着以同样的方式找B的mex值,这显然是最优的


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    int n,ans,c[111];
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    signed main(){
    	for (rr int T=iut();T;--T){
    		n=iut(); rr int ans=0,j=0;
    		for (rr int i=0;i<101;++i) c[i]=0;
    		for (rr int i=1;i<=n;++i) ++c[iut()];
    		for (;j<101&&c[j];++j); ans=j;
    		for (rr int i=0;i<j;++i) --c[i];
    		for (rr int i=0;i<101;++i)
    		if (!c[i]) {ans+=i; break;}
    		printf("%d
    ",ans);
    	}
    	return 0;
    } 
    

    CF1406B Maximum Product

    洛谷传送门
    CF1406B


    分析

    考虑枚举负数的选择个数,如果为偶数个就使得所有数绝对值的乘积尽量大,
    奇数个就使得所有数绝对值的乘积尽量小,0特判一下答案至少为0,将正数负数分别降序排序即可


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=100011; typedef long long lll;
    int n1,n2,a[N],b[N]; lll ans;
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(lll ans){
    	if (ans<0) putchar('-'),ans=-ans;
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline lll max(lll a,lll b){return a>b?a:b;}
    signed main(){
    	for (rr int Test=iut();Test;--Test,putchar(10)){
    		rr lll ans=-1e18; n1=0,n2=0;
    		for (rr int T=iut();T;--T){
    			rr int x=iut();
    		    if (!x) ans=0;
    		    else if (x>0) a[++n1]=x;
    		      else b[++n2]=x;
    		}
    		if (n1+n2<5) {print(ans); continue;}
    		sort(a+1,a+1+n1),reverse(a+1,a+1+n1),
    		sort(b+1,b+1+n2),reverse(b+1,b+1+n2);
    		if (n1>4) ans=(lll)a[1]*a[2]*a[3]*a[4]*a[5];
    		rr int mx=n1>4?1:(5-n1),mn=n2<5?n2:5;
    		for (rr int i=mx;i<=mn;++i)
    		switch (i){
    			case 1:{
    				ans=max(ans,(lll)b[1]*a[n1]*a[n1-1]*a[n1-2]*a[n1-3]);
    				break;
    			}
    			case 2:{
    				ans=max(ans,(lll)b[n2]*b[n2-1]*a[1]*a[2]*a[3]);
    				break;
    			}
    			case 3:{
    				ans=max(ans,(lll)b[1]*b[2]*b[3]*a[n1]*a[n1-1]);
    				break;
    			}
    			case 4:{
    				ans=max(ans,(lll)b[n2]*b[n2-1]*b[n2-2]*b[n2-3]*a[1]);
    				break;
    			}
    			case 5:{
    				ans=max(ans,(lll)b[1]*b[2]*b[3]*b[4]*b[5]);
    				break;
    			}
    		}
    		print(ans);
    	}
    	return 0;
    }
    

    CF1406C Link Cut Centroids

    洛谷传送门
    CF1406C


    分析

    考虑一棵树的重心最多只有两个,纵使有也必须相邻,
    那么考虑将一个叶子节点拼接到一个重心上,那另外一个就不是重心了


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=100011; struct node{int y,next;}e[N<<1];
    int siz[N],big[N],as[N],et,deg[N],root,Y,X,SIZ,n;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed max(int a,int b){return a>b?a:b;}
    inline void dfs(int x,int fa){
    	siz[x]=1,big[x]=0;
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fa){
    		dfs(e[i].y,x);
    		siz[x]+=siz[e[i].y];
    		big[x]=max(big[x],siz[e[i].y]);
    	}
    	big[x]=max(big[x],SIZ-siz[x]);
    	if (big[x]<big[root]) root=x;
    }
    signed main(){
    	for (rr int T=iut();T;--T){
    		n=iut(),et=1;
    		for (rr int i=1;i<n;++i){
    			rr int x=iut(),y=iut();
    			e[++et]=(node){y,as[x]},as[x]=et,++deg[y],
    			e[++et]=(node){x,as[y]},as[y]=et,++deg[x];
    		}
    		for (rr int i=2;i<=n;++i) if (deg[i]==1) {Y=i; break;}
    		X=e[as[Y]].y,big[0]=SIZ=n-1,root=0,dfs(X,Y);
            printf("%d %d
    %d %d
    ",X,Y,root,Y);
    		for (rr int i=1;i<=n;++i) deg[i]=as[i]=siz[i]=big[i]=0;
    	}
    	return 0;
    } 
    

    CF1406D Three Sequences

    洛谷传送门
    CF1406D


    分析

    考虑一种构造形式,(a)上升的部分由(b)完成,(a)下降的部分由(c)完成,
    实际上区间加只会影响左端点和右端点,可以差分完成,注意向上取整


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=100011;
    typedef long long lll;
    lll a[N],n,ans;
    inline lll iut(){
    	rr lll ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(lll ans){
    	if (ans<0) putchar('-'),ans=-ans;
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline lll max(lll a,lll b){return a>b?a:b;}
    signed main(){
    	n=iut();
    	for (rr int i=1;i<=n;++i) a[i]=iut();
    	for (rr int i=n;i>1;--i) a[i]-=a[i-1];
    	for (rr int i=2;i<=n;++i) ans+=max(a[i],0);
    	print((ans+a[1]+1)>>1),putchar(10);
    	for (rr int Q=iut();Q;--Q){
    		rr int l=iut(),r=iut()+1,x=iut();
    		if (l>1) ans+=max(a[l]+x,0)-max(a[l],0); a[l]+=x;
    		if (r<=n) ans+=max(a[r]-x,0)-max(a[r],0),a[r]-=x;
    		print((ans+a[1]+1)>>1),putchar(10);
    	}
    	return 0;
    }
    

    CF1406E Deleting Numbers

    洛谷传送门
    CF1406E


    分析

    考虑对答案(x)进行质因数分解,直接询问质数的指数幂会超过询问次数,
    考虑根号内的质数这么处理求得当前结果(now),根号外的质数最多出现一次
    如果(now>1)直接判断(p*now)是否出现,否则答案就是大质数,考虑将大质数分块,
    每100个先全部删完再(A 1)判断是否有剩余,有剩余直接再判断一次,最大询问次数不超过给定询问次数


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    int n,prime[10011],v[100011],ans,Cnt,Y;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline signed A(int x){
    	printf("A %d
    ",x);
    	fflush(stdout);
    	return iut();
    }
    inline signed B(int x){
    	printf("B %d
    ",x);
    	fflush(stdout);
    	return iut();
    }
    signed main(){
    	n=iut();
    	if (n==1){
    		printf("C 1
    "),fflush(stdout);
    		return 0; 
    	}
    	for (rr int i=2;i<=n;++i){
    		if (!v[i]) prime[++Cnt]=i;
    		for (rr int j=1;j<=Cnt&&prime[j]<=n/i;++j){
    			v[i*prime[j]]=1;
    		    if (i%prime[j]==0) break;
    		}
    	}
    	for (Y=1;prime[Y]*prime[Y]<=n;++Y); --Y;
    	ans=1;
    	for (rr int i=1;i<=Y;++i){
    		B(prime[i]);
    		for (;prime[i]<=n/ans&&A(ans*prime[i]);ans*=prime[i]);
    	}
    	if (ans>1){
    		for (rr int i=Y+1;i<=Cnt&&prime[i]<=n/ans;++i)
    		    if (A(ans*prime[i])) {ans*=prime[i]; break;}
    		printf("C %d
    ",ans),fflush(stdout);
    		return 0;
    	}
    	for (rr int i=Y+1,las=A(1);i<=Cnt;i+=100){
    		rr int mn=i+99>Cnt?Cnt:(i+99),now;
    		for (rr int j=i;j<=mn;++j) B(prime[j]);
    		now=A(1);
    		if (las-now<mn-i+1){
    			for (rr int j=i;j<=mn;++j)
    			if (A(prime[j])) {ans=prime[j]; break;}
    			printf("C %d
    ",ans),fflush(stdout);
    		    return 0;
    		}
    		las=now;
    	}
    	printf("C %d
    ",ans),fflush(stdout);
    	return 0; 
    }
    
  • 相关阅读:
    一、第一个小程序
    Golang学习笔记
    第四章 自上而下分析
    个人vim配置
    第三章 词法分析
    3.7 TCP拥塞控制
    3.6 拥塞控制原理
    3.5 面向连接的运输:TCP
    3.4可靠数据传输的原理
    3.3 无连接运输:UDP
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14513171.html
Copyright © 2020-2023  润新知