Codeforces Round #628 (Div. 2) 题解

A.EhAb AnD gCd

题面:https://codeforces.com/contest/1325/problem/A

思路

任何数和和\(1\)\(lcm\)都是他自己,\(gcd\)都是\(1\),因此输出的答案为\(1\)\(x-1\)即可

AC代码
#include <bits/stdc++.h>
typedef long long ll;
#define inf_int 0x3f3f3f3f
#define inf_ll 0x3f3f3f3f3f3f3f3f
int main() {
    int T; scanf("%d", &T);
    while (T--) {
        int x; scanf("%d", &x);
        printf("%d %d\n", 1, x-1);
    }
}

B.CopyCopyCopyCopyCopy

题面:https://codeforces.com/contest/1325/problem/B

思路

\(n\)个数字,复制\(n\)份,且要求严格递增。当前的数为\(x\),在下一份复制中必然要找的数大于\(x\)

对此,我们求有多少个不重复的数字就行了。

AC代码
#include <bits/stdc++.h>
typedef long long ll;
#define inf_int 0x3f3f3f3f
#define inf_ll 0x3f3f3f3f3f3f3f3f
int arr[100005];
int main() {
    int T; scanf("%d", &T);
    while (T--) {
        int n; scanf("%d", &n);
        std::set<int> st; st.clear();
        for (int i = 0; i <n;i++) scanf("%d", &arr[i]), st.insert(arr[i]);
        printf("%d\n", st.size());
    }
}

C.Ehab and Path-etic MEXs

题面:https://codeforces.com/contest/1325/problem/C

思路

越长的链有限度越低,那我们来个长链剖分,然后进行贪心就好了就好了。

然而事实上没有这么复杂,就当练了长链剖分就好了

AC代码
#include <bits/stdc++.h>
using namespace std;
const int SIZE=1e5 + 10;
struct edge{//邻接表存数据
    int to,nex,w,id;
}e[SIZE<<1];
struct cv {
    int id, cnt;
    bool operator < (const cv& tb) {return cnt < tb.cnt;}
}shk[SIZE];
int n,cnt,ans,rt,sum;
int head[SIZE],son[SIZE],f[SIZE],d[SIZE],t[5];
bool vis[SIZE];
void add(int x,int y,int w,int _id){//邻接表插入
    e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;e[cnt].id = _id;
    e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=w;e[cnt].id = _id;
}
void Get_Root(int x,int fa){
    son[x]=1;f[x]=0;
    for(int i=head[x];i;i=e[i].nex){
        if(!vis[e[i].to] && e[i].to != fa){
            Get_Root(e[i].to,x);
            son[x]+=son[e[i].to];
            f[x]=max(f[x],son[e[i].to]);
        }
    }
    f[x]=max(f[x],sum-son[x]);
    if(f[x]<f[rt])rt=x;
}
int siz[SIZE];
void dfs(int u, int fa) {
    siz[u] = 1;
    for (int i = head[u]; i; i = e[i].nex) {
        int y = e[i].to;
        if (y != fa) {
            dfs(y, u);
            siz[u] += siz[y];
            shk[e[i].id].cnt = siz[y];
            shk[e[i].id].id = e[i].id;
        }
    }
}
int res[SIZE];
int main(){
    rt = 0;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int u,v; scanf("%d%d",&u,&v);
        add(u,v,1,i);
    }
    f[0]=sum=n;
    Get_Root(1,0);
    dfs(rt, 0);

    sort(shk+1, shk+n);
    for (int i = 1; i < n; i++) {
        res[shk[i].id] = i;
    }
    for (int i = 1; i < n; i++) {
        printf("%d\n", res[i]-1);
    }
}

D.Ehab the Xorcist

题面:https://codeforces.com/contest/1325/problem/D

思路

最多只会输出3种情况。

因为异或是不进位的加法,所以当\(u > v\)的时候直接不行就行了。

\(u\)\(v\)奇偶不一致时,也是不行的。

\(u=v\)时,那么只有一个数,即\(u\)\(v\)本身。

一开始没看到要求输出的数最少,后来发现来不及了。

AC代码
#include <bits/stdc++.h>
typedef long long ll;
#define inf_int 0x3f3f3f3f
#define inf_ll 0x3f3f3f3f3f3f3f3f
int main() {
    ll u, v; scanf("%lld%lld", &u, &v);
    if (u > v || ((u&1) != (v&1))) printf("-1");
    else if (u==0 && v ==0) printf("0");
    else if (u == v) printf("1\n%lld", u);
    else {
        ll w = (v - u) >> 1;
        if ((u & w) == 0) {
            printf("2\n%lld %lld",u+w, w);
        }
        else printf("3\n%lld %lld %lld",u, w, w);
    }
}
posted @ 2020-03-25 21:14  tudouuuuu  阅读(140)  评论(0编辑  收藏  举报