Codeforces round #628

A. EhAb AnD gCd
给你一个 x x ,让你构造一个 A , B A,B ,然后问你 L C A ( A , B ) + L C M ( A , B ) = x LCA(A,B)+LCM(A,B)=x
思路:
还想了一会。。。直接构造1 x 1 x-1 就ok了。
B
给你一个串,你可以无限延长复制它,然后问你LIS长度。
思路:
把给的字符串排个序,然后这个字符串LIS就是答案。
C
题意:
给你一棵树,然后让你给树的边上赋权值,权值大小为: [ 0 , n 2 ] [0,n-2] 让你输出方案,使得任意两点之间的MEX的最大值最小。
MEX是两点之间路径上不曾出现的最小非负整数。
思路:
我们可以发现,总会有一条路径上会有 0 , 1 0,1 ,所以我们尽可能不让2和他们在一个路径上。
然后我的思路就是用 d f s dfs 找一条树上的最长链,进行放置权值,先放0,1和其他,最后放置2。现在想想这真是个糟糕的思路,我们只需要找一个度大于等于3的点放置完0,1,2,其余随便放置就可以了。难受。。。最后还是贴的ZHJ的代码,ZHJ ORZ!果然还是我太弱了。。。

vector<int> G[N];
vector<pair<int,int> > vp;
map<pair<int,int> ,int> hap;
int deg[N];
int main(){
    int n = read();
    rep(i,1,n-1){
        int u = read(),v = read();
        deg[u] ++;
        deg[v] ++;
        vp.push_back({u,v});
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int co(0);
    rep(i,1,n){
        if(deg[i] >= 3){
            int S = G[i].size();
            rep(j,0,2){
                int y = G[i][j];
                hap[{i,y}] = hap[{y,i}] = co++;
            }
            break;
        }
    }
    int S = vp.size();
    rep(i,0,S-1){
        int x = vp[i].first,y = vp[i].second;
        if(hap.count({x,y})) cout<<hap[{x,y}]<<endl;
        else {
            cout<<co++<<endl;
        }
    }
}

D
题意很简短,但构造过程不好想。
给你一个 u u v v ,然后让你构造一个元素个数最小的数组,使得这些数字的异或和为 u u ,前缀和为 v v
思路:
异或又被称为不进位加法,
a + b = a b + 2 a & b a+b=a\oplus b+ 2\cdot a\&b
这个式子可以这样理解, a b a\oplus b 只是计算出每一位不考虑进位时候的情况,可以 + + 还是进位的,进位的时候肯定是 a , b a,b 当前位都是1,才会往前进位。而 a & b a\&b i i 为1,说明第 i i 位该往前进位,而乘2则是整体左移,就是往前进位。然后在加上刚才没考虑进位的情况。
这个题目不存在解的情况,就是 u > v u>v 的情况和 u , , v u,,v 奇偶性不同的情况。前者是因为异或是不进位加法,所以肯定不会大于加法的值;后者是因为,如果某一位 u , v u,v 不一致,则肯定是进位造成的,而最后一位肯定没有进位,所以要为1都为1,要为0,都为0。
对于 u = = v u==v 的情况直接输出 u u 就行了。
对于一般情况,
a b = u a\oplus b=u

a + b = a b + 2 a & b a+b=a\oplus b+ 2\cdot a\&b
   = u + 2 a & b = v \qquad \ \ =u+2\cdot a\&b=v

因为 u x x = u u\oplus x\oplus x=u
所以
我们令 x = v u 2 x=\dfrac{v-u}{2} 就行了
答案就是 [ u , x , x ] [u,x,x]
可是第一个样例长度为2啊
这是因为 u x = u + x u\oplus x=u+x
所以是 [ u + x , x ] [u+x,x]

int main(){
    ll a = read(),b = read();
    if(a==b&&a==0) {return puts("0"),0;}
    else if(a==b) {cout<<1<<'\n'<<a<<endl;return 0;}
    if(a > b|| ((a&1)!=(b&1))) {puts("-1");return 0;}
    ll x = (b - a)>>1;
    if((a^x)==(a+x)) cout<<2<<'\n'<<a+x<<' '<<x<<endl;
    else cout<<3<<'\n'<<a<<' '<<x<<' '<<x;
}
发布了636 篇原创文章 · 获赞 38 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/104881193