CF Round #628 div2
CF Round #628 div2
A.构造##
给定x
求n,m,使得他们GCD+LCM=x
取1,x-1即可
B.数学##
给定长为n的数字串,它复制了n次,求LIS
set记录下即可
C.构造##
给定一棵无向树,你要给每条边单独标记0-n-1中的一个数字,使得任意两点(u,v)组成的路径对应的所有MEX值中,最大值最小。MEX指的是(u,v)路径上没出现过的最小非零数,就是SG函数里面的那个意思。
这题要理解清楚的一个点,就是这个图并非SG函数里面的有向图,他是无向的,这点我一开始没有反应过来。既然全部无向,那么任意两点均存在路径联通,也就是说必定有一条路径上要出现0,1以及0,2,那么如果某条路径上同时出现了0,1,2,那么它的最大的MEX最小也要3起步了,所以在树结构中,我们只要把一个连接了三个点以上的点记录下来,并且把它的三条边给值0,1,2,那么最大MEX也死活不会比3大(说实话,这题最好还要特判一下只有一条边的情况,出题人可能默认它这样给就不是树)
D.数学##
给定u和v,求构造数量最少的几个数,使他们的异或和为u,和为v。
这题不着急使用bitset
应该冷静分析一下,首先异或和最重要的性质,a+b与aXORb的奇偶性一致,因为异或加它可能会抵消某个bit上的两个1,减少的必定是2的倍数。
那么如果uv奇偶不同或者u比v大,就无解。
异或第二个重要性质,bXORAXORA==b,那么为了使数量最少,并且v-u的差值为偶数,我们就找三个数u,2个(v-u)/2即可
但是这里有个神坑的地方
就是很容易忽略u与其中的一个(v-u)/2可以合并的情况,判断一下u与(v-u)/2的含1bit不相同即可.(样例1就卡死)
ac记录:
#include<iostream>
#include<cstring>
using namespace std;
#define INF 1e10+5
#define maxn 105
#define minn -105
#define ld long double;
#define uint unsigned int;
#define ull unsigned long long;
typedef long long ll;
int main()
{
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(false);
ll u,v;
cin>>u>>v;
if(u>v||(v-u)&1)
{
cout<<-1<<endl;
return 0;
}
if(u==v)
{
if(!u)cout<<0<<endl;
else cout<<1<<endl<<u<<endl;
return 0;
}
ll half=((v-u)>>1);
if((half&u)==0)
{
cout<<2<<endl<<half<<" "<<(half^u)<<endl;
}
else
{
cout<<3<<endl<<half<<" "<<half<<" "<<u<<endl;
}
return 0;
}