zoukankan      html  css  js  c++  java
  • Codeforces Round #628 (Div. 2)

    A. EhAb AnD gCd

    You are given a positive integer x. Find any such 2 positive integers a and b such that GCD(a,b)+LCM(a,b)=x.
    As a reminder, GCD(a,b) is the greatest integer that divides both a and b. Similarly, LCM(a,b) is the smallest integer such that both a and b divide it.
    It's guaranteed that the solution always exists. If there are several such pairs (a,b), you can output any of them.
    Input
    The first line contains a single integer t (1≤t≤100) — the number of testcases.
    Each testcase consists of one line containing a single integer, x (2≤x≤109).
    Output
    For each testcase, output a pair of positive integers a and b (1≤a,b≤109) such that GCD(a,b)+LCM(a,b)=x. It's guaranteed that the solution always exists. If there are several such pairs (a,b), you can output any of them.
    Example
    input
    2
    2
    14
    output
    1 1
    6 4
    Note
    In the first testcase of the sample, GCD(1,1)+LCM(1,1)=1+1=2.
    In the second testcase of the sample, GCD(6,4)+LCM(6,4)=2+12=14.

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    int main(){
        int T,x;
        cin>>T;
        while(T--){
            cin>>x;
            cout<<1<<" "<<x-1<<endl;
        }
        return 0;
    }
    

    B. CopyCopyCopyCopyCopy

    Ehab has an array a of length n. He has just enough free time to make a new array consisting of n copies of the old array, written back-to-back. What will be the length of the new array's longest increasing subsequence?
    A sequence a is a subsequence of an array b if a can be obtained from b by deletion of several (possibly, zero or all) elements. The longest increasing subsequence of an array is the longest subsequence such that its elements are ordered in strictly increasing order.
    Input
    The first line contains an integer t — the number of test cases you need to solve. The description of the test cases follows.
    The first line of each test case contains an integer n (1≤n≤105) — the number of elements in the array a.
    The second line contains n space-separated integers a1, a2, …, an (1≤ai≤109) — the elements of the array a.
    The sum of n across the test cases doesn't exceed 105.
    Output
    For each testcase, output the length of the longest increasing subsequence of a if you concatenate it to itself n times.
    Example
    input
    2
    3
    3 2 1
    6
    3 1 4 1 5 9
    output
    3
    5
    Note
    In the first sample, the new array is [3,2,1,3,2,1,3,2,1]. The longest increasing subsequence is marked in bold.
    In the second sample, the longest increasing subsequence will be [1,3,4,5,9].

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    const int N=1e5+10;
    int a[N];
    set<int> S;
    int main(){
        int T;
        cin>>T;
        while(T--){
            int n;
            cin>>n;
            S.clear();
            for(int i=1,x;i<=n;++i){
                cin>>x;
                S.insert(x);
            }
            cout<<S.size()<<endl;
        }
        return 0;
    }
    

    C. Ehab and Path-etic MEXs

    You are given a tree consisting of n nodes. You want to write some labels on the tree's edges such that the following conditions hold:
    Every label is an integer between 0 and n−2 inclusive.
    All the written labels are distinct.
    The largest value among MEX(u,v) over all pairs of nodes (u,v) is as small as possible.
    Here, MEX(u,v) denotes the smallest non-negative integer that isn't written on any edge on the unique simple path from node u to node v.
    Input
    The first line contains the integer n (2≤n≤105) — the number of nodes in the tree.
    Each of the next n−1 lines contains two space-separated integers u and v (1≤u,v≤n) that mean there's an edge between nodes u and v. It's guaranteed that the given graph is a tree.
    Output
    Output n−1 integers. The ith of them will be the number written on the ith edge (in the input order).
    Examples
    input
    3
    1 2
    1 3
    output
    0
    1
    input
    6
    1 2
    1 3
    2 4
    2 5
    5 6
    output
    0
    3
    2
    4
    1

    思路:
    给一棵树上的所有边赋一个0~n-2且不重复的权值,求任意两个节点上的所有边的权值的不包含的最小正权值最小(就是SG打表用的mex函数)。写的时候没多想,贪心把权值从0开始依次给叶节点到父节点,再到子节点给父节点。有一个简单且容易证明正确的思路:当树是一条链时无论怎么赋答案都是n,当有一个节点有3个以上的儿子,就把0,1,2三个权值分别赋给它的任意三条边,这样任意两个节点都不会同时走到这三条边,这样的答案最大就是2。

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    const int N=1e5+10;
    int son[N];
    int head[N],cnt=0;
    struct ac{
        int v,nex,ans;
    }edges[N*2];
    int inq[N],outq[N],n;
    void addedge(int u,int v){
        edges[++cnt]=(ac){v,head[u],-1};
        head[u]=cnt;
    }
    int main(){
        cin>>n;
        memset(inq,0,sizeof inq);
        memset(outq,0,sizeof outq);
        memset(head,-1,sizeof head);cnt=0;
        for(int i=1,u,v;i<=n-1;++i){
            cin>>u>>v;
            addedge(u,v);
            addedge(v,u);
            son[u]++;
            son[v]++;
        }
        queue<int> q;
        for(int i=1;i<=n;++i){
            if(son[i]==1){
                q.push(i);
                inq[i]=1;
            }
        }
        int now=0;
        while(!q.empty()){
            int u=q.front();q.pop();
            outq[u]=1;
            for(int i=head[u];~i;i=edges[i].nex){
                int v=edges[i].v;
                if(outq[v]) {
                    continue;
                }
                if(!inq[v]){
                    q.push(v);
                    inq[v]=1;
                }
                edges[i].ans=now++;
            }
        }
        for(int i=1;i<=cnt;++i){
            if(edges[i].ans!=-1){
                cout<<edges[i].ans<<endl;
            }
        }
        return 0;
    }
    

    D. Ehab the Xorcist

    Given 2 integers u and v, find the shortest array such that bitwise-xor of its elements is u, and the sum of its elements is v.
    Input
    The only line contains 2 integers u and v (0≤u,v≤1018).
    Output
    If there's no array that satisfies the condition, print "-1". Otherwise:
    The first line should contain one integer, n, representing the length of the desired array. The next line should contain n positive integers, the array itself. If there are multiple possible answers, print any.
    Examples
    input
    2 4
    output
    2
    3 1
    input
    1 3
    output
    3
    1 1 1
    input
    8 5
    output
    -1
    input
    0 0
    output
    0
    Note
    In the first sample, 3⊕1=2 and 3+1=4. There is no valid array of smaller length.
    Notice that in the fourth sample the array is empty.

    思路:给出(u,v)求最短的序列(a_1...a_n),满足序列异或之和等于u,加和等于v.如果无解输出-1。首先我们需要考虑到异或运算是不进位加法,那么可以确定无解的条件就是(v>u)。再者(xXORx=0),为了得到最短,我们可以得到序列(x,x,u),所以(x=(v-u)/2),如果(v-u)等于奇数也是无解。这样交了两发还是wa了。还有一种情况:对于x和u二进制下没有都是1的位置,那么可以把x合并到u上,既不影响异或运算也不会让和减小了。

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #include<set>
    #include<map>
    #define re0 return 0
    using namespace std;
    typedef pair<int,int> PII;
    typedef long long LL;
    int main(){
        LL u,v;
        cin>>u>>v;
        if(u==0&&v==0){
            puts("0");
            re0;
        }
        if(u>v||(v-u)%2) {
            puts("-1");
            re0;
        }
        if(u==v){
            cout<<1<<endl;
            cout<<v<<endl;
            re0;
        }
        LL t=(v-u)/2;
        if( (u^t)==t+u){
            cout<<2<<endl;
            cout<<u+t<<" "<<t<<endl;
            re0;
        }
        cout<<3<<endl;
        cout<<u<<" "<<t<<" "<<t<<endl;
    }
    
  • 相关阅读:
    C# 静态类和非静态类的区别
    C# 集合
    C#字符串
    C# 虚方法 抽象方法 接口
    C#常用的关键字
    扫描功能小结 (扫描二维码、条形码)
    QQ空间/朋友圈类界面的搭建
    tableview左滑按钮 tableviewcell自定义左滑按钮
    UITextView 开始编辑时,文字没有左上角对齐解决办法 tableview整体上移
    图片、视频上传小记(基于七牛云)
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12517280.html
Copyright © 2011-2022 走看看