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;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12517280.html