Codeforces Round #628 (Div. 2)
A
假数论。
拆成x-1
和1
即可。
B
没有比在每次copy中找一个点来构成大序列的LIS更优的做法了,那么set.size()即可。
C
卡了有点久…只要将度数最高的点的儿子们置为0、1、...、du[v] - 1
即可满足最大的MEX值最小。这是因为无论怎么置数,在01之间一定有一条路径,那么MEX至少为2;而我们的这种构造办法满足了无论路径怎么选取,MEX值都不会大于2,所以不等式取到等号,即该构造办法最优。
D
卡死了…
倒不是因为难…可能是因为没有好好看题目…
当时脑子里只想着数组长度要么是1要么是2,或者是00的特判0…就是没想到u == v && u != 0
时长度可以为1…??
做法不算困难,如果v - u在位wei
上为1,并且u在wei - 1
上为0,那么就可以在这里分裂出两个
2
w
e
i
−
1
2^{wei-1}
2wei−1分别给u和 0
,从而在两数和中构成
2
w
e
i
2^{wei}
2wei;而当u在wei - 1
上不为0,那么就不能用两个长度来完成该等式,此时要用三个长度,同样分裂出2个
2
w
e
i
−
1
2^{wei-1}
2wei−1分配给两个0
,结合另一个不变的数u
构成三数和获得
2
w
e
i
2^{wei}
2wei。
据此,如果差值v - u
是一个负数或是一个奇数,显然都不能满足上述的构造过程,此时应输出-1
。
代码
vector<int> vec;
int main(){
// Fast;
ll u, v; scanf("%lld %lld", &u, &v);
if(u == v){
if(u == 0) puts("0");
else printf("1\n%lld\n", u);
return 0;
}
if(v - u < 0 || (v - u) & 1) puts("-1");
else{
v -= u;
int fail = 0;
for(int wei = 1; wei < 63; wei++) if(v & (1LL << wei)){
vec.push_back(wei - 1);
if(u & (1LL << (wei - 1))) fail = 1;
}
if(!fail){
ll x = u, y = 0;
for(auto i: vec){
x |= 1LL << i; y |= 1LL << i;
}
printf("2\n%lld %lld\n", x, y);
}
else{
ll x = 0;
fro(auto i: vec) x |= 1LL << i;
printf("3\n%lld %lld %lld\n", u, x, x);
}
}
return 0;
}
EF 过(补)的人好像挺多的,但是现在题目是无穷无尽的…这两题我在场上也没有看,没有必要去这样做新题…所以就先放一放吧
明天周三打一下训练联盟的周赛,免得变成一个2h选手(其实是1h选手)…
另外之后的一段时间打算做一下dp专题训练…只打思维题不打牢知识点基础就容易像我现在这样从小蓝人变成小绿人… = =
实在是太菜了