耻辱场,必铭记
A a,b只要输出1 x-1就是lcm(a,b)+gcd(a,b)=x了
B 记录数组放到set里,答案set.size
C 只要把他的叶子结点连接的那几条线变成最小的距离即可,但有一个特殊样例
2
1 2
0
因为我是用出现次数是1的就是叶子结点,所有我wa在19,赛后冷静下来思考了一波,觉得自己是真的比赛的时候不相信自己
细节也不注意。
#include <bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long #define il inline #define it register int #define inf 0x3f3f3f3f #define lowbit(x) (x)&(-x) #define pii pair<int,int> #define mak(n,m) make_pair(n,m) #define mem(a,b) memset(a,b,sizeof(a)) #define mod 998244353 const int maxn=1e5+10; int n; int u,v,ans[maxn],vis[maxn],pos[maxn]; int main(){ mem(ans,-1); scanf("%d",&n); for(int i=1;i<n;i++){ scanf("%d%d",&u,&v); vis[u]++;vis[v]++;pos[u]=i;pos[v]=i; } int t=0; for(it i=1;i<=n;i++){ if(vis[i]==1){ ans[pos[i]]=t++; } } for(it i=n-1;i>=1;i--){ if(ans[i]==-1){ ans[i]=t++; } } for(it i=1;i<n;i++){ if(ans[i]==n-1){ans[i]=0;} printf("%d ",ans[i]); } return 0; }
D
题意:
x,y
求最少的数组个素和其元素,元素异或和为x,元素累加为y
我的思路:
x把他变为二进制,存一个数组a,
用另外一个数组b进行模拟,,把答案存在c这个数组,从0开始往上
首先,b0=y,(y-a0)%2==1 输入-1,然后y-=a0,如果a0是1,那么zhi+=1<<0,b1=y/2。
到b1这层,如果a1是1,那么zhi+=1<<a1,b1-=a1,b1%2==1 那么进行b1减一,b0现在等于2,查看(zhi>>(1))&1,如果是1 ,就去查看数组c里面(ci>>(1))==0,ci+=1<<(1),如果凑不足两个,就c数组中添入1<<(i-1),如果b1==0 a1==1这种情况输出-1,以此类推循环64次足够了
是不是很麻烦,比赛的时候写了这种,写完发现比赛快结束了,交了几分,都错了,然后发现1 1我输出-1,然后赛后检查发现少些了一个else,然后就ac了
#include<iostream> #include<map> #include<set> #include<queue> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define ll long long #define ull unsigned long long #define il inline #define it register int #define inf 0x3f3f3f3f #define lowbit(x) (x)&(-x) #define pii pair<int,int> #define mak(n,m) make_pair(n,m) #define mem(a,b) memset(a,b,sizeof(a)) #define mod 998244353 const int maxn=1e5+10; ll n,m; ll a[110],b[110],da[maxn]; int main(){ scanf("%lld%lld",&n,&m); if(n==0){ if(m==0){printf("0 ");return 0;} else if(m&1){ printf("-1 ");return 0; } else{ printf("2 "); printf("%lld %lld",m/2,m/2);return 0; } } ll ans=n,sum=m; int c=0,cc=0; while(ans){ a[c++]=ans%2; ans/=2; } int f=0,p=0; ll daa=0; b[0]=m; for(it i=0;i<=100;i++){ if(a[i] && b[i]){ b[i]--;daa+=(ll)1<<i; } else if(a[i] && !b[i]){f=1;break;}//就是这里少了个else,淦 if(b[i]%2==1){ if(i==0){f=1;break;} int ff=2; if(!((daa>>(i-1))&1)){ daa+=((ll)1<<(i-1));ff--; } for(it j=0;j<p;j++){ if((da[j]>>(i-1))&1){continue;} if(ff){ da[j]+=(ll)1<<(i-1);ff--; } } for(it j=0;j<ff;j++){ da[p++]=(ll)1<<(i-1); } b[i]--; } b[i+1]+=b[i]/2; } if(f){printf("-1 ");return 0;} da[p++]=daa; printf("%d ",p); for(it i=0;i<p;i++){ printf(i==p-1?"%lld ":"%lld ",da[i]); } return 0; }
至于为什么说我的思路呢,因为官方给的题解比我的简单很多:
看代码就马上知道,其思路了
#include <bits/stdc++.h> using namespace std; int main() { long long u,v; scanf("%I64d%I64d",&u,&v); if (u%2!=v%2 || u>v) { printf("-1"); return 0; } if (u==v) { if (!u) printf("0"); else printf("1 %I64d",u); return 0; } long long x=(v-u)/2; if (u&x) printf("3 %I64d %I64d %I64d",u,x,x); else printf("2 %I64d %I64d",(u^x),x); }
就是x和y,如果前面条件都符合,最后如果u=(y-x)/2,当u和x有交集的情况,就是三个x,x,u(x^x=0),如果没交集就可以合并u^x,x