Codeforces Round #628 (Div. 2)

Codeforces Round #628 (Div. 2)

http://codeforces.com/contest/1325

A - EhAb AnD gCd

#include
using namespace std;
int t,x;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&x);
		printf("1 %d\n",x-1);
	}
	return 0;
}

B - CopyCopyCopyCopyCopy

思路:因为要严格递增,事实上每个最多取到一次,然后原数组复制了n遍,即在每一遍中取一个数即可,等于说可以将原数组中的数按任意顺序取出,那么排好序后严格递增的子序列就是最优

#include
#define MAXN 100005
using namespace std;
int n,a[MAXN],t;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i = 1;i <= n;++i)
			scanf("%d",&a[i]);
		sort(a+1,a+n+1);
		int cnt = 1;
		for(int i = 2;i <= n;++i)
			if(a[i] > a[i-1])
				++cnt;
		printf("%d\n",cnt);
	}
	return 0;
}

C - Ehab and Path-etic MEXs

思路:因为最长那段肯定要有0,1,2,…这样连续的数字,如果要放0,1,0,1必然会出现在一条路径上,直接找到连有至少三条边的节点将0,1,2分别分配给3边即可让他们三不会出现在同一条路径

#include
#define MAXN 100005
using namespace std;
int n,head[MAXN],tot;
inline void init()
{
	tot = 0;
	memset(head,-1,sizeof(int)*(n+1));
}
struct edge
{
	int u,v,x;
}edg[MAXN];
int du[MAXN];
vector ve[MAXN];
int main()
{
	scanf("%d",&n);
	int u,v;
	for(int i = 1;i < n;++i)
	{
		scanf("%d%d",&u,&v);
		edg[i].u = u,edg[i].v = v;
		++du[u],++du[v];
		ve[u].push_back(i),ve[v].push_back(i);
		edg[i].x = -1;
	}
	int cnt = 0;
	for(int i = 1;i <= n;++i)
	{
		if(du[i] >= 3)
		{
			for(int j = 0;j < ve[i].size();++j)
			{
				edg[ve[i][j]].x = cnt;
				++cnt;
			}
			break;
		}
	}
	for(int i = 1;i < n;++i)
		if(edg[i].x == -1)
		{
			edg[i].x = cnt;
			++cnt;
		}
	for(int i = 1;i < n;++i)
		printf("%d\n",edg[i].x);
	return 0;
}

D - Ehab the Xorcist

思路:首先设a[1]为u,a[2],a[3]为0,很明显要在不改变异或值的情况下只能让两个数字同时异或上一个数,而0,1同时异或上一个数和不变,故异或后和必然增大,u <= v
如果v-u为奇数,那么末位会有个1需要加上,但末位必须有两个数字都异或上1总的异或值才不会改变,故v-u必须为偶数
将v-u分为两份,设tmp = (v-u)/2,即tmp中1的位需要有两个数字异或上
现假设要异或上一个1,当a[1]中对应位为0时,直接将这一位变为1然后a[2]的这一位也变为1即可
但如果a[1]中对应位为1,让a[1]去异或上它sum不会增大,故让a[2],a[3]异或上它
最终可以发现a[1] = u|tmp,a[2] = tmp,a[3] = u&tmp
再把0剔除掉即可

#include
#define ll long long
using namespace std;
ll u,v,a[5];
int main()
{
	scanf("%lld%lld",&u,&v);
	if(u > v || ((v-u)&1))
		printf("-1\n");
	else if(u == v)
	{
		if(u == 0)
			printf("0\n");
		else 
			printf("1\n%lld\n",u);
	}
	else
	{
		a[2] = a[3] = 0;
		ll tmp = (v-u)/2;
		a[1] = u | tmp;
		a[3] = u & tmp;
		a[2] = tmp;
		int n = 0;
		for(int i = 1;i <= 3;++i)
			if(a[i])
				++n;
		printf("%d\n",n);
		for(int i = 1;i <= n;++i)
			printf("%lld ",a[i]);
	}
	return 0;
}

你可能感兴趣的:(CF)