题意
给定x求出a,b使得gcd(a,b)+lcm(a,b)=x
题解
一个是1,x-1另一个就是 1 和任意数的最大公约数都是1,1和任意数的最小公倍数都是任意数的值
1 #include <bits/stdc++.h>
2 #define ll long long
3 #define mem(a,v) memset(a,v,sizeof (a))
4 using namespace std;
5 const int N=2010,INF=0x3f3f3f3f;
6 void solve(){
7 int x;
8 cin>>x;
9 cout<<"1"<<' '<<x-1<<endl;
10 }
11 int main(){
12 int t;
13 cin>>t;
14 while(t--){
15 solve();
16 }
17 }
题意
给定长度为n的序列,将n复制n次后求最长上升子序列
题解
排序去重即可
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1e5+10;
4 int n;
5 void solve(){
6 scanf("%d",&n);
7 vector<int>a(n);
8 for(int i=0;i<n;i++){
9 scanf("%d",&a[i]);
10 }
11 sort(a.begin(),a.end());
12 a.erase(unique(a.begin(),a.end()),a.end());
13 cout<<a.size()<<endl;
14 }
15 int main(){
16 int t;
17 scanf("%d",&t);
18 while(t--){
19 solve();
20 }
21
22 }
题意
给定一颗含有n个结点,在树的n-1条边中分别标记0~n-2
mex(u,v)表示在点u~v的所有边中没有出现的标记中的最小值
最后使的所有(u,v)的mex(u,v)中的最大值尽可能的小
题解
mex(u,v)表示除了从u到v中其他边的标记的最小值,最小的一定不能在一个点的同一个路径上,
即使是树链,除去始点和终点,最大的mex值也不会超过2,将度最大的点的边分配最小的即可
1 #include <bits/stdc++.h>
2 #define pii pair<int,int>
3 #define fi first
4 #define se second
5 #define pb push_back
6 using namespace std;
7 const int N=1e5+10;
8 vector<int>v[N];
9 int ans[N];
10 int main(){
11 int n;
12 scanf("%d",&n);
13 for(int i=1;i<n;i++){
14 int a,b;
15 scanf("%d%d",&a,&b);
16 v[a].pb(i);
17 v[b].pb(i);
18 ans[i]=-1;
19 }
20 pii maxv{0,0};
21 for(int i=1;i<=n;i++){
22 maxv=max(maxv,{v[i].size(),i});
23 }
24 int now=0;
25 for (int i=0;i<v[maxv.se].size();i++)
26 ans[v[maxv.se][i]]=now++;
27 for(int i=1;i<n;i++){
28 if(ans[i]==-1)
29 ans[i]=now++;
30 printf("%d\n",ans[i]);
31 }
32 }
题意
给定u,v求出一个最短的数组满足数组元素的异或和为u,总和为v,不存在输出-1
u,v<=1018
题解
如果u>v的话必定无解,如果u=v=0那么必定只有一个元素且长度为1,u=v ≠0 那么就是u,最长的情况就是[u,(v-u)/2,(v-u)/2]
如果不满足一个的情况考虑是否存在a,b使得a^b=u,a+b=v
考虑u,x,x 使u和x合起来为a,x为b
u^x^x=0,所以u+x后x为1的u也必定为1,用u&x来判断是否满足,如果u和x二进制位相等的话,显然u&v=0若不相等的话显然u&v也为0
所以如果u&x=0证明既满足了和为v又满足了异或和为u
如果u-v不能被2整除显然无解
注意要long long
1 #include <bits/stdc++.h> 2 #define pii pair<int,int> 3 #define fi first 4 #define se second 5 #define pb push_back 6 #define ll unsigned long long 7 using namespace std; 8 9 int main(){ 10 ll u,v; 11 scanf("%lld%lld",&u,&v); 12 if(u>v || (v-u)%2){ 13 puts("-1"); 14 return 0; 15 } 16 if(u==v && v==0){ 17 puts("0"); 18 return 0; 19 } 20 if(u==v && v!=0){ 21 printf("1\n%lld",u); 22 return 0; 23 } 24 ll d=(v-u)/2; 25 if(u&d){ 26 printf("3\n%lld %lld %lld",u,d,d); 27 } 28 else 29 printf("2\n%lld %lld",u+d,d); 30 }