Codeforces Round #627 (Div. 3) 题解

C o d e f o r c e s   R o u n d   627 ( D i v . 3 ) \mathrm{Codeforces \ Round \ 627 (Div. 3)} Codeforces Round 627(Div.3) 题解

这场比赛也叫做手速场(人均 A K AK AK场)

A   Y e t   A n o t h e r   T e t r i s   P r o b l e m \mathrm{A\ Yet \ Another \ Tetris \ Problem} A Yet Another Tetris Problem

  • 一眼题,判奇偶性即可,还有如果本身就一个数字也是 Y E S \mathrm{YES} YES
  • C o d e \mathcal{Code} Code
#include 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

bool rem;
int t,n,s,i,a;

int main()
{
	
	t=read();
	while(t--)
	{
		n=read(),s=read();
		s&=1;
		rem=0;
		for ( int i=2;i<=n;i++ )  
		{
			scanf("%d",&a);
			if(s!=(a&1))rem=1;
		}
		puts((rem&&n>1?"NO":"YES"));
	}
	return 0;
}

B   Y e t   A n o t h e r   P a l i n d r o m e   P r o b l e m \mathrm{B \ Yet \ Another\ Palindrome \ Problem} B Yet Another Palindrome Problem

  • 又是一眼题,只要判断两个相同的数之间的间隔是否大于等于 3 3 3即可,以及判断一下原串的长度即可。

  • C o d e \mathcal{Code} Code

#include 
using namespace std;
const int N=10000;

int T,n,pos[N],a[N];

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

int main()
{
	T=read();
	while (T--)
	{
		n=read();
		memset(pos,0,sizeof(pos));
		bool ww=false;
		for ( int i=1; i<=n; ++i) 
		{
			a[i]=read();
			if (!pos[a[i]]) pos[a[i]]=i;
			else if (i-pos[a[i]]>1) ww=true;
		}
		if(n<3) ww=false;
		if(ww) printf("YES\n");
		else printf("NO\n");
	}	
	return 0;	
}

C   F r o g   J u m p s \mathrm{C \ Frog \ Jumps} C Frog Jumps

  • 怎么又是一眼题啊。首先把 c 0 = c n + 1 = R c_0=c_{n+1}=R c0=cn+1=R,然后判断两个 R R R之间的最大距离即可。

  • C o d e \mathcal{Code} Code

#include 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

string str;
int t,n,last,d,i;

inline void solve()
{
	cin>>str;
	int n=str.size();
	int last=0,d=0;
	for ( int i=0;i<n;i++ ) 
		if(str[i]=='R')d=max(d,i+1-last),last=i+1;
	printf("%d\n",max(d,n+1-last));
}

int main()
{
	t=read();
	while(t--) solve();
	return 0;
}

D   P a i r   o f   T o p i c s \mathrm{D \ Pair \ of \ Topics} D Pair of Topics

  • 一道大套路题

  • a i + a j > b i + b j a_i+a_j>b_i+b_j ai+aj>bi+bj,那么有 a i − b i < b j − a j a_i-b_iaibi<bjaj,然后分别存下 a i − b i a_i-b_i aibi以及 b i − a i b_i-a_i biai,离散去重一下,树状数组求逆序对类似即可。

  • C o d e \mathcal{Code} Code

#include 
#define int long long
#define lowbit(x) x&(-x)

using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}


const int N=4e5+5; 

int n,m,ans,a[N],b[N],c[N],d[N],e[N];

inline void add(int x,int val)
{
	while(x<=m)
	{
		c[x]+=val;
		x+=lowbit(x);
	}
}

inline int ask(int x)
{
	int ret=0;
	while(x)
	{
		ret+=c[x];
		x-=lowbit(x);
	}
	return ret;
}

signed main()
{
	n=read();
	for ( int i=1;i<=n;i++ ) a[i]=read();
	for ( int i=1;i<=n;i++ )
	{
		b[i]=read();
		d[i*2-1]=a[i]-b[i];
		d[i*2]=b[i]-a[i];
	}
	sort(d+1,d+2*n+1);
	m=unique(d+1,d+2*n+1)-d-1;
	for ( int i=1;i<=n;i++ ) 
	{
		int p=lower_bound(d+1,d+m+1,b[i]-a[i])-d;
		ans+=i-ask(p)-1;
		p=lower_bound(d+1,d+m+1,a[i]-b[i])-d;
		add(p,1);
	}
	printf("%lld\n",ans);
	return 0;
}
		

E   S l e e p i n g   S c h e d u l e \mathrm{E \ Sleeping \ Schedule} E Sleeping Schedule

  • 什么题啊,没样例解释直接 G G \mathrm{GG} GG。其实就是个 d p dp dp
  • f i , j f_{i,j} fi,j表示到 i i i为几点选择 a i a_i ai
  • g i , j g_{i,j} gi,j表示到 i i i为几点选择 a i − 1 a_i-1 ai1
  • 然后就是随便转移(大雾, E E E还这么智障嘛,发现 F F F更简单啊)
  • C o d e \mathcal{Code} Code
#include
using namespace std;

int g[2005],f[2005];
bool vis[2005],bo[2005];

#define mem(i,j) memset(i,j,sizeof i)
#define mec(i,j) memcpy(i,j,sizeof i)

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

int n,h,l,r,i,a,j,ans=0;

int main()
{
	
	n=read();
	h=read();
	l=read();
	r=read();
	bo[0]=1;
	while(n--)
	{
		a=read();
		for ( int i=0;i<h;i++ ) 
		if(bo[i])
		{
			j=(i+a)%h;
			g[j]=f[i]+(j>=l&&j<=r);
			vis[j]=1;
		}
		for ( int i=0;i<h;i++ ) 
		if(bo[i])
		{
			j=(i+a-1)%h;
			g[j]=max(g[j],f[i]+(j>=l&&j<=r));
			vis[j]=1;
		}
		mec(f,g);
		mem(g,0);
		mec(bo,vis);
		mem(vis,0);
	}
	for ( int i=0;i<h;i++ ) 
		if(bo[i])
			ans=max(ans,f[i]);
	printf("%d\n",ans);
	return 0;
}

F   M a x i m u m   W h i t e   S u b t r e e \mathrm{F \ Maximum \ White \ Subtree} F Maximum White Subtree

  • 这道题目真的睿智。按照 x g c xgc xgc的原话:看着样例瞎猜都 A A A得了。的确是这样啊。

  • 简单得树形 D P DP DP

  • 首先预处理一遍每个节点以 1 1 1为根得最大。然后再 d f s dfs dfs一遍,如果不是根,且原来小于 0 0 0,只能寄希望于父亲。如果大于 0 0 0就与父亲比大小就好了。具体实现看代码。

  • C o d e \mathcal{Code} Code

#include 
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

const int N=2e5+5;

int n,m,col[N],c[N],f[N];
vector<int> ma[N];

inline void dfs(int u,int fa)
{
	if(col[u]) f[u]=1; else f[u]=-1;
	for ( int i=0;i<ma[u].size();i++ )
	{
		int v=ma[u][i];
		if(v==fa) continue;
		dfs(v,u);
		f[u]=max(f[u],f[v]+f[u]);
	}
}

inline void dfs2(int u,int fa)
{
	if(u!=1) 
	{
		if(f[u]<0) f[u]=max(f[u],f[u]+f[fa]);
		else f[u]=max(f[u],f[fa]);
	}
	for ( int i=0;i<ma[u].size();i++ )
	{
		int v=ma[u][i];
		if(v==fa) continue;
		dfs2(v,u);
	}
}

int main()
{
	n=read();
	for ( int i=1;i<=n;i++ ) col[i]=read();
	for ( int i=1;i<n;i++ )
	{
		int x,y;
		x=read(),y=read();
		ma[x].push_back(y);
		ma[y].push_back(x);
	}
	dfs(1,0);
	dfs2(1,0);
	for ( int i=1;i<=n;i++ ) printf("%d ",f[i]);
	return 0;
}
	

E E \mathrm{EE} EE环节

  • 发现自己手速不行啊,但小号还是上了 149 149 149分(一场上蓝祭祀
  • 好像 A − E \mathrm{A-E} AE所有代码主程序加起来还不及一个树剖啊。

你可能感兴趣的:(codeforces比赛,codeforces)