Codeforces Round #655 (Div. 2)题解

本来打算写垫底记的,结果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");
    }
}
View Code

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;
}
View Code

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]);
}
View Code

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]);
}
View Code
原文地址:https://www.cnblogs.com/hfctf0210/p/13337727.html