A题
题意:
给n个数据,m次操作,使得1~A,全都出现。如果其中有数据没在n里出现,就m--
思路:
模拟就行
#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 #define fi first #define se second #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const int maxn=1e3+10; ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;} int t,n,m; int v[maxn]; int main(){ scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); int a;mem(v,0); for(it i=0;i<n;i++){ scanf("%d",&a);v[a]=1; } int maxx=0; for(it i=1;m;i++){ if(v[i]==0){v[i]=1;m--;maxx=i;} else{maxx=i;} } for(it i=maxx+1;;i++){ if(v[i]){maxx=i;} else{break;} } printf("%d ",maxx); } return 0; }
B题
题意:
给n个数据,这写数据范围,1<=a[i]<=n-1
问能不能割断,比如
2 1 3 4 | 2 1,这样左边就是1234,右边12
如果有输出全部,如果没有输出0
思路:
从前遍历,从后遍历,出现两次相同的数字就是不符合,如果没重复的个数达到最大值,记录位置。
再验证一下后面的数据是否符合条件,比如有可能2 1 3 4 1 1这种。
还有wa了一次是因为,如果从前遍历,从后遍历,相同位置,就输出一个即可,比如1 2 2 1
#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 #define fi first #define se second #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const int maxn=2e5+10; ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;} int t,n,m; int a[maxn],vis[maxn]; int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); mem(vis,0);int f=1,maxx=-1; for(it i=1;i<=n;i++){ scanf("%d",&a[i]); //vis[a[i]]++; if(maxx<a[i]){maxx=a[i];} } int ge=0; for(it i=1;i<=n;i++){ if(vis[a[i]]==0){ge++;vis[a[i]]=1;} else{f=0;break;} if(ge==maxx){ge=i;break;} } int ff=2,g2=0;mem(vis,0); for(it i=n;i>=1;i--){ if(vis[a[i]]==0){g2++;vis[a[i]]=1;} else{ff=0;break;} if(g2==maxx){g2=i;break;} } //cout<<ge<<g2<<endl; if(!f && !ff){printf("0 ");} else{ if(f){ int zhi=n-ge; for(it i=1;i<=zhi;i++){vis[i]=0;} for(it i=ge+1;i<=n;i++){ vis[a[i]]++; } for(it i=1;i<=zhi;i++){ if(vis[i]==0){f=0;break;} } } if(ff){ int zhi=g2; for(it i=1;i<zhi;i++){vis[i]=0;} for(it i=1;i<zhi;i++){ vis[a[i]]++; } for(it i=1;i<zhi;i++){ if(vis[i]==0){ff=0;break;} } } if(!f && !ff){printf("0 ");} else{ if(ff && f){ if(ge==g2-1){ printf("1 %d %d ",ge,n-ge); } else{ printf("2 %d %d %d %d ",ge,n-ge,g2-1,n-g2+1); } } else if(f){ printf("1 %d %d ",ge,n-ge); } else{ printf("1 %d %d ",g2-1,n-g2+1); } } } } return 0; }
D题
题意:
You are given two integers d,md,m, find the number of arrays aa, satisfying the following constraints:
- The length of aa is nn, n≥1n≥1
- 1≤a1<a2<⋯<an≤d1≤a1<a2<⋯<an≤d
- Define an array bb of length nn as follows: b1=a1b1=a1, ∀i>1,bi=bi−1⊕ai∀i>1,bi=bi−1⊕ai, where ⊕⊕ is the bitwise exclusive-or (xor). After constructing an array bb, the constraint b1<b2<⋯<bn−1<bnb1<b2<⋯<bn−1<bn should hold.
Since the number of possible arrays may be too large, you need to find the answer modulo mm.
看条件就了解,找到符合的种类
思路:
因为是位运算,我一开始想的是二进制,然后1,2,4,8的找规律,样例给了规律
就是1(二进制一位),转换成2 (二进制两位)的时候是+2,2转换4(二进制三位)的是+6,4转换位8(二进制四位)的是+30
1 2 3 4 5 6 7 8 9
1 3 5 11 17 23 29 59 89
2 2 6 6 6 6 30 30
刚好是4前面3的数据+1,8前面7的数据+1,比赛的时候脑瘫,不相信这规律,特地验证了一波,为什么是+1,举个例子8为什么是加30,因为会出现1 8这种数据,其他29就是前者数据后面都加个8(别问为什么举例的是8,呜呜呜)
证明完以后就十分钟写,因为数据10^9,所以要存二进制,分别用a存二进制位数时候要+多少,b存二进制位数前一个数据量是多少。#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 1000000007 #define fi first #define se second #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const int maxn=1e5+10; ll ksm(ll a,ll b){if(b<0)return 0;ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;} int t; ll n,m; ll a[40],b[40]; int main(){ scanf("%d",&t); while(t--){ scanf("%lld%lld",&n,&m); if(n==1){printf("%d ",n%m);continue;} ll k=n; ll c=0; while(k){ if(k==0){break;} c++;k>>=1; } a[0]=1,a[1]=2;b[0]=1;b[1]=1; for(ll i=2;i<=c;i++){ ll c=(ll)1<<i,c1=(ll)1<<(i-1); b[i]=((c-c1)%m*a[i-1]%m+b[i-1])%m; a[i]=(b[i]+1)%m; } // cout<<a[5]<<a[3]<<a[4]<<endl; //cout<<b[2]<<b[3]<<b[4]<<endl; printf("%lld ",(b[c-1]%m+((n+1-(1<<(c-1)))*a[c-1])%m)%m); } return 0; }
有1说1,十二分钟搓出来,都没来得及交上去。呜呜呜迷惑C题,