A.EhAb AnD gCd
思路
任何数和和(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
", 1, x-1);
}
}
B.CopyCopyCopyCopyCopy
思路
有(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
", st.size());
}
}
C.Ehab and Path-etic MEXs
思路
越长的链有限度越低,那我们来个长链剖分,然后进行贪心就好了就好了。
然而事实上没有这么复杂,就当练了长链剖分就好了
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
", res[i]-1);
}
}
D.Ehab the Xorcist
思路
最多只会输出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
%lld", u);
else {
ll w = (v - u) >> 1;
if ((u & w) == 0) {
printf("2
%lld %lld",u+w, w);
}
else printf("3
%lld %lld %lld",u, w, w);
}
}