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\n",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\n%d %d\n",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\n",x);
	fflush(stdout);
	return iut();
}
inline signed B(int x){
	printf("B %d\n",x);
	fflush(stdout);
	return iut();
}
signed main(){
	n=iut();
	if (n==1){
		printf("C 1\n"),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\n",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\n",ans),fflush(stdout);
		    return 0;
		}
		las=now;
	}
	printf("C %d\n",ans),fflush(stdout);
	return 0; 
}
posted @ 2021-03-10 17:39  lemondinosaur  阅读(60)  评论(0编辑  收藏  举报