本来打算写垫底记的,结果Unrated了,所以是题解了。
AB
太水了不写了
C
看到unrated就没写了,其实挺简单的。
容易发现答案只可能是0/1/2,情况如下:
0:无错误序列
1:错误序列均连续
2:其他情况(可以将其变为错误序列连续)

#include<bits/stdc++.h> using namespace std; const int N=2e5+7; int main() { int T,n,num,L,R; cin>>T; while(T--) { cin>>n; R=num=0,L=n+1; for(int i=1,x;i<=n;i++) { scanf("%d",&x); if(x!=i)num++,L=min(L,i),R=max(R,i); } if(!num)puts("0"); else if(num==R-L+1)puts("1"); else puts("2"); } }
D
思维题,老年选手思维不行。
乍看区间DP,但只能O(n^2),然后发现是邻位前缀和

#include<bits/stdc++.h> using namespace std; #define ll long long const int N=2e5+7; int n,a[N]; ll s0[N],s1[N],ans; int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d",&a[i]); if(n==1){printf("%d",a[1]);return 0;} s1[1]=a[1]; for(int i=2;i<=n;i++)if(i&1)s1[i]=s1[i-2]+a[i];else s0[i]=s0[i-2]+a[i]; ans=s1[n]; for(int i=1;i<n;i+=2)ans=max(ans,s0[n-1]-s0[i-1]+s1[i]); for(int i=2;i<n;i+=2)ans=max(ans,s1[n]-s1[i-1]+s0[i]); cout<<ans; }
E
这才是区间DP,f[l][r]表示在l,r列中间,格子完全包括在区间内的1所造成的影响,枚举中间列k,能填的尽量往k填,取最大即可,复杂度O(nm^3/6)

#include<bits/stdc++.h> using namespace std; const int N=150; int n,m,al[N][N],ar[N][N],f[N][N]; int main() { scanf("%d%d",&n,&m); for(int i=1,t,x,y;i<=n;i++) { scanf("%d",&t); while(t--) { scanf("%d%d",&x,&y); for(int j=x;j<=y;j++)al[i][j]=x,ar[i][j]=y; } } for(int l=m;l;l--) for(int r=l;r<=m;r++) for(int k=l;k<=r;k++) { int x=0; for(int i=1;i<=n;i++)if(l<=al[i][k]&&ar[i][k]<=r)x++; f[l][r]=max(f[l][r],f[l][k-1]+f[k+1][r]+x*x); } printf("%d",f[1][m]); }
F
采用递归分治思想,数组单调不降,因此保证区间[r+1-f,l-1+f]为x,可以扔掉继续找。细节比较多,具体见code

#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+7; int n, a[N],b[N]; map<int,int>mp; void solve(int l,int r) { if(l>r)return; int x,f; printf("? %d %d ",l,r),fflush(stdout); scanf("%d%d",&x,&f); if(r-l+1==f){for(int i=l;i<=r;i++)a[i]=x;mp[x]=l;return;} auto p=mp.lower_bound(x); int pos=-1; if(p!=mp.end()&&p->first==x)pos=p->second; else{ p--; for(int i=max(l,p->second+f);;i+=f) { int a,b;printf("? %d %d ",i,i),fflush(stdout); scanf("%d%d",&a,&b); mp[a]=i; if(a==x){pos=i;break;} } } int aa,bb,pl,pr; printf("? %d %d ",max(l,pos-f+1),pos),fflush(stdout); scanf("%d%d",&aa,&bb); if(aa==x)pl=pos-bb+1,pr=pos-bb+f; else{ printf("? %d %d ",pos,min(pos+f-1,r)),fflush(stdout); scanf("%d%d",&aa,&bb); pl=pos+bb-f,pr=pos+bb-1; } for(int i=pl;i<=pr;i++)a[i]=x; solve(l,pl-1),solve(pr+1,r); } int main() { scanf("%d",&n); mp[0]=0; solve(1,n); printf("!"); for(int i=1;i<=n;i++)printf(" %d",a[i]); }