反HACK
查看原帖
反HACK
557754
Kalenist楼主2023/5/17 13:10

目测可以通过全部原始+HACK数据。解释先咕着。

#include<bits/stdc++.h>
#define N 210
#define For(i,a,b) for(register int i=a;i<=b;i++)
#define Down(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
int n,x,v[N<<1],f[N<<1][N],g[N<<1][N],ans[N],l[N],r[N],cnt[N<<1][N<<1],prep[N<<1][N],sufp[N<<1][N],must[N<<1][N<<1];
int main()
{
    freopen("festival.in","r",stdin);
    freopen("festival.out","w",stdout);
    scanf("%d",&n),v[++v[0]]=-1;
    For(i,1,n)
    {
        scanf("%d%d",l+i,&x),r[i]=l[i]+x-1;
        v[++v[0]]=l[i],v[++v[0]]=r[i];
    }
    v[++v[0]]=0x3f3f3f3f,sort(v+1,v+v[0]+1);
    v[0]=unique(v+1,v+v[0]+1)-v-1;
    For(i,1,n)
    {
        l[i]=lower_bound(v+1,v+v[0]+1,l[i])-v;
        r[i]=lower_bound(v+1,v+v[0]+1,r[i])-v;
    }
    For(i,1,v[0]) For(j,1,v[0]) For(k,1,n) if(l[k] >= i && r[k] <= j) cnt[i][j]++;
	For(j,0,n)
	{
	    int npos=1;
		For(i,1,v[0])
		{
		    while(cnt[npos+1][i] >= j && npos < i) npos++;
			if(cnt[npos][i] >= j) prep[i][j]=npos;
		}
	}
	For(j,0,n)
	{
	    int npos=v[0];
		Down(i,v[0],1)
		{
		    while(cnt[i][npos-1] >= j && npos > i) npos--;
			if(cnt[i][npos] >= j) sufp[i][j]=npos;
		}
	}
	memset(f,-0x3f,sizeof(f)),f[0][0]=0;
    For(i,1,v[0]) For(j,0,n)
	{
	    f[i][j]=max(f[i][j],f[i-1][j]);
	    For(k,0,n)
        {
	        if(!prep[i][k]) break;
            f[i][j]=max(f[i][j],f[prep[i][k]-1][j]+k);
            if(j >= k) f[i][j]=max(f[i][j],f[prep[i][k]-1][j-k]);
        }
	}
    memset(g,-0x3f,sizeof(g)),g[v[0]+1][0]=0;
    Down(i,v[0],1) For(j,0,n)
	{
	    g[i][j]=max(g[i][j],g[i+1][j]);
	    For(k,0,n)
	    {
	        if(!sufp[i][k]) break;
		    g[i][j]=max(g[i][j],g[sufp[i][k]+1][j]+k);
		    if(j >= k) g[i][j]=max(g[i][j],g[sufp[i][k]+1][j-k]);
	    }
	}
    memset(must,-0x3f,sizeof(must));
    For(i,1,v[0]) For(j,i+2,v[0])
    {
        int pos=n,a=-0x3f3f3f3f,b=-0x3f3f3f3f;
        For(k,0,n)
        {
            if(f[i][k] < 0) break;
            while(pos >= 0)
            {
			    int now=min(f[i][k]+g[j][pos],k+pos+cnt[i+1][j-1]);
				if(now < a) break;
                a=now,pos--;
            }
            pos++;
        }
		pos=n;
		For(k,0,n)
		{
		    if(f[i][k] < 0) break;
			while(pos >= 0)
			{
			    int now=min(f[i][k]+g[j][pos]+cnt[i+1][j-1],k+pos);
				if(now < b) break;
				b=now,pos--;
			}
			pos++;
		}
		must[i][j]=max(a,b);
    }
    For(i,1,n)
	{
	    For(j,1,l[i]-1) For(k,r[i]+1,v[0])
		    ans[i]=max(ans[i],must[j][k]);
		ans[0]=max(ans[0],ans[i]);
	}
    For(i,0,n) printf("%d\n",ans[i]);
    return 0;
}

2023/5/17 13:10
加载中...