A. Ehab Fails to Be Thanos
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You’re given an array a of length 2n. Is it possible to reorder it in such way so that the sum of the first n elements isn’t equal to the sum of the last n elements?
Input
The first line contains an integer n (1≤n≤1000), where 2n is the number of elements in the array a.
The second line contains 2n space-separated integers a1, a2, …, a2n (1≤ai≤106) — the elements of the array a.
Output
If there’s no solution, print “-1” (without quotes). Otherwise, print a single line containing 2n space-separated integers. They must form a reordering of a. You are allowed to not change the order.
Examples
inputCopy
3
1 2 2 1 3 1
outputCopy
2 1 3 1 1 2
inputCopy
1
1 1
outputCopy
-1
Note
In the first example, the first n elements have sum 2+1+3=6 while the last n elements have sum 1+1+2=4. The sums aren’t equal.
In the second example, there’s no solution.
题意:给出一个序列,改变元素的次序,要求新序列前半部分的和与后半部分的和不等
题解:直接排序即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
int a[10005];
int main()
{
int n;
cin>>n;
for(int i=1;i<=2*n;i++)cin>>a[i];
sort(a+1,a+1+2*n);
if(a[1]!=a[2*n]){
for(int i=1;i<=2*n;i++){
printf("%d",a[i]);
char cc=(i==2*n)?'\n':' ';
printf("%c",cc);
}
}
else{
printf("-1\n");
}
return 0;
}
B. Ehab Is an Odd Person
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You’re given an array a of length n. You can perform the following operation on it as many times as you want:
Pick two integers i and j (1≤i,j≤n) such that ai+aj is odd, then swap ai and aj.
What is lexicographically the smallest array you can obtain?
An array x is lexicographically smaller than an array y if there exists an index i such that xi<yi, and xj=yj for all 1≤j<i. Less formally, at the first index i in which they differ, xi<yi
Input
The first line 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.
Output
The only line contains n space-separated integers, the lexicographically smallest array you can obtain.
Examples
inputCopy
3
4 1 7
outputCopy
1 4 7
inputCopy
2
1 1
outputCopy
1 1
Note
In the first example, we can swap 1 and 4 since 1+4=5, which is odd.
题意:给出一个序列,如果ai+aj的值是奇数,就可以交换ai和aj,求一个字典序最小的新序列
题解:如果同时存在奇数和偶数,那么所有元素都可以经过一个中间元素进行交换,所以直接排序即可。否则就不能进行交换。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
int a[100005];
int main()
{
int n;
scanf("%d",&n);
int o=0;
int e=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]%2)o++;
else e++;
}
if(o&&e){
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
printf("%d",a[i]);
char cc=(i==n)?'\n':' ';
printf("%c",cc);
}
}
else{
for(int i=1;i<=n;i++){
printf("%d",a[i]);
char cc=(i==n)?'\n':' ';
printf("%c",cc);
}
}
return 0;
}
C. Ehab and a Special Coloring Problem
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You’re given an integer n. For every integer i from 2 to n, assign a positive integer ai such that the following conditions hold:
For any pair of integers (i,j), if i and j are coprime, ai≠aj.
The maximal value of all ai should be minimized (that is, as small as possible).
A pair of integers is called coprime if their greatest common divisor is 1.
Input
The only line contains the integer n (2≤n≤105).
Output
Print n−1 integers, a2, a3, …, an (1≤ai≤n).
If there are multiple solutions, print any of them.
Examples
inputCopy
4
outputCopy
1 2 1
inputCopy
3
outputCopy
2 1
Note
In the first example, notice that 3 and 4 are coprime, so a3≠a4. Also, notice that a=[1,2,3] satisfies the first condition, but it’s not a correct answer because its maximal value is 3.
题意:求一个序列,a2~an n个元素,要求i和j互质的时候ai!=aj,要求序列中最大的ai最小
题解:易知最大的ai应该为2~n内素数的个数。线性筛素数的过程,每个非质数都只会被最小的素数筛掉,同时可以在这时求出所有ai
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
int pri[100005],ip[100005],cnt,iw[100005];
void getprime(int x){
for(int i=2;i<=x;i++){
if(!ip[i]){pri[++cnt]=i;iw[i]=cnt;}
for(int j=1;j<=cnt&&pri[j]*i<=x;j++){
ip[i*pri[j]]=1;
iw[i*pri[j]]=iw[pri[j]];
if(i%pri[j]==0)break;
}
}
}
int main()
{
int n;
scanf("%d",&n);
getprime(n);
for(int i=2;i<=n;i++){
printf("%d",iw[i]);
char cc=(i==n)?'\n':' ';
printf("%c",cc);
}
return 0;
}
D. Ehab and the Expected XOR Problem
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Given two integers n and x, construct an array that satisfies the following conditions:
for any element ai in the array, 1≤ai<2n;
there is no non-empty subsegment with bitwise XOR equal to 0 or x,
its length l should be maximized.
A sequence b is a subsegment of a sequence a if b can be obtained from a by deletion of several (possibly, zero or all) elements from the beginning and several (possibly, zero or all) elements from the end.
Input
The only line contains two integers n and x (1≤n≤18, 1≤x<218).
Output
The first line should contain the length of the array l.
If l is positive, the second line should contain l space-separated integers a1, a2, …, al (1≤ai<2n) — the elements of the array a.
If there are multiple solutions, print any of them.
Examples
inputCopy
3 5
outputCopy
3
6 1 3
inputCopy
2 4
outputCopy
3
1 3 1
inputCopy
1 1
outputCopy
0
Note
In the first example, the bitwise XOR of the subsegments are {6,7,4,1,2,3}.
题意:求一个最长的序列,要求元素1<=ai<2^n,并且任意区间的异或和不等于0或x
题解:正着考虑构造ai不容易想出,而考虑前缀异或和,每次选出一个数作为sumi,而每选出一个sumi,后面就不能选sumi和sumi^x了,这样就可以构造出所有的sumi,根据sumi ^ sumi-1就可以求出ai,易知这样得到的序列已经是最长的了,因为每次选数会标记两个数不可用,并且不可能有一种方式只标记一个数或者不标记
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
int sum[5000005];
int main()
{
ll n,x;
scanf("%lld%lld",&n,&x);
set<int>st;
for(ll i=1;i<(1ll<<n);i++)st.insert(i);
if(x<(1ll<<n))st.erase(x);
int tot=0;
for(int i=1;;i++){
//debug(st.size());
if(st.size()==0){
//printf("0\n");
//return 0;
break;
}
tot++;
set<int>::iterator it=st.begin();
sum[i]=(*it);
st.erase((*it));
//debug()
if(st.count(sum[i]^x))st.erase(sum[i]^x);
//debug(st.size());
}
printf("%d\n",tot);
for(int i=1;i<=tot;i++){
printf("%d",sum[i]^sum[i-1]);
char cc=(i==tot)?'\n':' ';
printf("%c",cc);
}
return 0;
}
E. Ehab and the Expected GCD Problem
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Let’s define a function f§ on a permutation p as follows. Let gi be the greatest common divisor (GCD) of elements p1, p2, …, pi (in other words, it is the GCD of the prefix of length i). Then f§ is the number of distinct elements among g1, g2, …, gn.
Let fmax(n) be the maximum value of f§ among all permutations p of integers 1, 2, …, n.
Given an integers n, count the number of permutations p of integers 1, 2, …, n, such that f§ is equal to fmax(n). Since the answer may be large, print the remainder of its division by 1000000007=109+7.
Input
The only line contains the integer n (2≤n≤106) — the length of the permutations.
Output
The only line should contain your answer modulo 109+7.
Examples
inputCopy
2
outputCopy
1
inputCopy
3
outputCopy
4
inputCopy
6
outputCopy
120
Note
Consider the second example: these are the permutations of length 3:
[1,2,3], f§=1.
[1,3,2], f§=1.
[2,1,3], f§=2.
[2,3,1], f§=2.
[3,1,2], f§=2.
[3,2,1], f§=2.
The maximum value fmax(3)=2, and there are 4 permutations p such that f§=2.
待补
F. Ehab and the Big Finale
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This is an interactive problem.
You’re given a tree consisting of n nodes, rooted at node 1. A tree is a connected graph with no cycles.
We chose a hidden node x. In order to find this node, you can ask queries of two types:
d u (1≤u≤n). We will answer with the distance between nodes u and x. The distance between two nodes is the number of edges in the shortest path between them.
s u (1≤u≤n). We will answer with the second node on the path from u to x. However, there’s a plot twist. If u is not an ancestor of x, you’ll receive “Wrong answer” verdict!
Node a is called an ancestor of node b if a≠b and the shortest path from node 1 to node b passes through node a. Note that in this problem a node is not an ancestor of itself.
Can you find x in no more than 36 queries? The hidden node is fixed in each test beforehand and does not depend on your queries.
Input
The first line contains the integer n (2≤n≤2⋅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
To print the answer, print “! x” (without quotes).
Interaction
To ask a question, print it in one of the formats above:
d u (1≤u≤n), or
s u (1≤u≤n).
After each question, you should read the answer: either the distance or the second vertex on the path, as mentioned in the legend.
If we answer with −1 instead of a valid answer, that means you exceeded the number of queries, made an invalid query, or violated the condition in the second type of queries. Exit immediately after receiving −1 and you will see Wrong answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.
After printing a query, do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:
fflush(stdout) or cout.flush() in C++;
System.out.flush() in Java;
flush(output) in Pascal;
stdout.flush() in Python;
See the documentation for other languages.
Hacks:
The first line should contain two integers n and x (2≤n≤2⋅105, 1≤x≤n).
Each of the next n−1 lines should contain two integers u and v (1≤u,v≤n) that mean there is an edge between nodes u and v. The edges must form a tree.
Example
inputCopy
5
1 2
1 3
3 4
3 5
3
5
outputCopy
d 2
s 3
! 5
Note
In the first example, the hidden node is node 5.
We first ask about the distance between node x and node 2. The answer is 3, so node x is either 4 or 5. We then ask about the second node in the path from node 3 to node x. Note here that node 3 is an ancestor of node 5. We receive node 5 as the answer. Finally, we report that the hidden node is node 5.
题意:交互题。给出一棵树,1为树的根节点,有一个要求的节点x,每次可以进行两种操作,操作一 d u ,得到从x到u的距离,操作二 s u,如果u是x的祖先,则得到从u到x的路径上的第二个点,如果u不是x的祖先,你的程序会wa。最多进行36次操作,求出这个节点x
题解:求出重儿子和重链。bot[v]表示v所在重链上的最底端节点,如果有dept[x]+depth[bot[v]]-2*depth[v]==dist(bot[v],x),那么可知v是LCA(bot[v],x),那么v和x在同一条链上,经过几次这样的操作之后就会得到一个v和x在同一条重链上,而此时这条重链的最底端节点bot[v]和x的LCA就是x
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" is "<<x<<endl;
const int maxn=2e5+5;
struct edge{
int to;
int nex;
}e[maxn<<1];
int cnt,head[maxn],depth[maxn],son[maxn],siz[maxn],bot[maxn];
void adde(int x,int y){
e[cnt].to=y;
e[cnt].nex=head[x];
head[x]=cnt++;
}
void dfs(int u,int f){
siz[u]=1;
for(int i=head[u];i!=-1;i=e[i].nex){
int v=e[i].to;
if(v==f)continue;
depth[v]=depth[u]+1;
dfs(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]){
son[u]=v;
}
}
}
void dfs2(int u,int f){
if(son[u]){
dfs2(son[u],u);
bot[u]=bot[son[u]];
}
else{
bot[u]=u;
}
for(int i=head[u];i!=-1;i=e[i].nex){
int v=e[i].to;
if(v==f||v==son[u])continue;
dfs2(v,u);
}
}
int main(){
int n;
scanf("%d",&n);
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
adde(a,b);
adde(b,a);
}
dfs(1,-1);
dfs2(1,-1);
printf("d 1\n");
fflush(stdout);
int deep;
scanf("%d",&deep);
int v=1;
while(1){
printf("d %d\n",bot[v]);
fflush(stdout);
int deep2;
scanf("%d",&deep2);
while(deep+depth[bot[v]]-2*depth[v]!=deep2){
v=son[v];
}
if(depth[v]==deep){
printf("! %d\n",v);
fflush(stdout);
return 0;
}
printf("s %d\n",v);
fflush(stdout);
scanf("%d",&v);
}
return 0;
}