您的位置:首页 > 其它

BZOJ4384: [POI2015]Trzy wieże

2016-05-10 09:32 387 查看
题目大意:要选一段最长的字符串,使得三种字符出现次数各不相同或只有一种

只有一种的直接就能扫出来,然后就想各不相同的

首先维护一个前缀和,代表到每个点时,前缀B,C,S的个数

然后令xi=bi-ci,yi=ci-si,zi=si-bi,每个点权值为自己的位置

如果两个点的xi,yi,zi均不相同,这一段就可以选

所以可以先按x排序,这样就干掉一维

然后我们设x相同的为一组,首先我们把包含权值为1的那一组提到最前面,包含权值为n的那组提到第二组的位置

然后维护6个树状数组

前三个维护最小值,分别代表y值与位置为1的y值相同而z值不同的最小值,以及z相同y不相同的,yz都不相同的

           查询的时候,如果他的yz都跟位置为1的不相同,那最小值直接就是1

          否则根据他的yz来决定去哪组查询最小值

后三个与这个同理,维护最大值

然后具体方式就是,对于每一组,先把这一组的都查询完,然后再插入

这时列一个表格可以发现,还是有一种情况没考虑到,就是最大值在第一组而最小值在第二组的情况,特殊处理一下就好了

神烦的代码,6800B+,除了树状数组基本啥也没有.....

61000msAC,吓尿我,估计如果我TLE了就不调了...正解1000B我也不知道是怎么做的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000010
using namespace std;
char s
;
int n;
struct ppp{int x,y,z,num;}a
,a1
,a2
;
int cnt1,cnt2;
bool cmp1(ppp x,ppp y){return x.x<y.x;}
struct BIT
{
int c[N<<1];
void changemx(int x,int v)
{
for(;x<=n+N;x+=x&-x)
c[x]=max(c[x],v);
}
void changemn(int x,int v)
{
// cout<<x-N<<'!'<<v<<endl;
for(;x<=n+N;x+=x&-x)
c[x]=min(c[x],v);
}
int checkmx(int x)
{
int ans=0;
for(;x;x-=x&-x)
ans=max(c[x],ans);
return ans;
}
int checkmn(int x)
{
// cout<<x-N<<'?';
int ans=707185547;
for(;x;x-=x&-x)
ans=min(ans,c[x]);
// cout<<ans<<endl;
return ans;
}
};
BIT zy,zz,ny,nz;
int main()
{
int i,j,k;
scanf("%d",&n);
scanf("%s",s+1);
// //cout<<s+1;return 0;
for(i=1;i<=n;i++)
{
a[i]=a[i-1];
a[i].num=i;
if(s[i]=='B') a[i].x++;
else if(s[i]=='C') a[i].y++;
else a[i].z++;
}
int o,p,q,oo,pp,qq;
for(i=1;i<=n;i++)
{
o=a[i].x;p=a[i].y;q=a[i].z;
a[i].x=o-p;a[i].y=p-q;a[i].z=q-o;
// cout<<a[i].x<<' '<<a[i].y<<' '<<a[i].z<<endl;
}
n++;a
.x=0;a
.y=0;a
.z=0;a
.num=0;

int ans=0;
o=a
.x;p=a
.y;q=a
.z;
oo=a[n-1].x;pp=a[n-1].y;qq=a[n-1].z;
//cout<<n;
sort(a+1,a+n+1,cmp1);
int s1,t1,s2,t2;
{
i=1;
while(a[i].x!=o) i++;
j=i;
while(a[j+1].x==a[i].x&&j<n) j++;
s1=i;t1=j;
for(k=i;k<=j;k++) cnt1++,a1[cnt1]=a[k];
i=1;
while(a[i].x!=oo) i++;
j=i;
while(a[j+1].x==a[i].x&&j<n) j++;
s2=i;t2=j;
for(k=i;k<=j;k++) cnt2++,a2[cnt2]=a[k];
// cout<<s1<<' '<<t1<<' '<<s2<<' '<<t2<<endl;
if(s1!=s2)
{
int e=max(t1,t2);j=e;
for(i=e;i>cnt1+cnt2;i--)
{
while((j>=s1&&j<=t1)||(j>=s2&&j<=t2)) j--;
// cout<<j;
a[i]=a[j];j--;
}
for(i=1;i<=cnt1;i++)
a[i]=a1[i];
for(i=1;i<=cnt2;i++)
a[i+cnt1]=a2[i];
{
/*puts("");
for(k=1;k<=n;k++)
cout<<a[k].x<<' '<<a[k].y<<' '<<a[k].z<<' '<<a[k].num<<endl;*/
int maxn=-1,p3,qqq;
for(k=1;k<=cnt1;k++)
{
if(a[k].num>maxn)
maxn=a[k].num,p3=a[k].y,qqq=a[k].z;
}
// cout<<maxn;
for(k=1;k<=cnt1;k++)
{
if(a[k].y!=p3)
{
zy.changemx(a[k].z+N,a[k].num);
ny.changemx(N+1-a[k].z,a[k].num);
}
if(a[k].z!=qqq)
{
zz.changemx(a[k].y+N,a[k].num);
nz.changemx(N+1-a[k].y,a[k].num);
}
}
//cout<<' '<<p3<<' '<<qqq<<endl;
for(k=cnt1+1;k<=cnt2+cnt1;k++)
{
if(a[k].y==p3)
{
ans=max(ans,zy.checkmx(a[k].z+N-1)-a[k].num+1);
ans=max(ans,ny.checkmx(N-a[k].z)-a[k].num+1);
if(a[k].z==qqq)
{
ans=max(ans,zz.checkmx(a[k].y+N-1)-a[k].num+1);
ans=max(ans,nz.checkmx(N-a[k].y)-a[k].num+1);
}
}
else
{
if(a[k].z==qqq)
{
// cout<<ans<<'!';
ans=max(ans,zz.checkmx(a[k].y+N-1)-a[k].num+1);
ans=max(ans,nz.checkmx(N-a[k].y)-a[k].num+1);
// cout<<ans<<endl;
}
else ans=max(ans,maxn-a[k].num+1);
}
//cout<<ans;
}
}
}
else
{
int e=t1;j=e;
for(i=e;i>cnt1;i--)
{
while(j>=s1&&j<=t1) j--;
a[i]=a[j];j--;
}
for(i=1;i<=cnt1;i++)
a[i]=a1[i];
}
}

memset(zy.c,0,sizeof(zy.c));
memset(zz.c,0,sizeof(zz.c));
memset(ny.c,0,sizeof(ny.c));
memset(nz.c,0,sizeof(nz.c));
i=1;
while(a[i].x!=oo) i++;
j=i;
while(a[j+1].x==a[i].x&&j<n) j++;
for(k=i;k<=j;k++)
{
// //cout<<k<<' ';
if(a[k].y!=pp)
{
//cout<<k<<a[k].z;
zy.changemx(a[k].z+N,a[k].num);
ny.changemx(N+1-a[k].z,a[k].num);
}
if(a[k].z!=qq)
{
zz.changemx(a[k].y+N,a[k].num);
nz.changemx(N+1-a[k].y,a[k].num);
}
}
i=1;
while(i<=n)
{
j=i;
while(a[j+1].x==a[i].x&&j<n) j++;
if(a[i].x==oo){i=j+1;continue;}
for(k=i;k<=j;k++)
{
if(a[k].y==pp)
{
ans=max(ans,zy.checkmx(a[k].z+N-1)-a[k].num+1);
ans=max(ans,ny.checkmx(N-a[k].z)-a[k].num+1);
if(a[k].z==qq)
{
ans=max(ans,zz.checkmx(a[k].y+N-1)-a[k].num+1);
ans=max(ans,nz.checkmx(N-a[k].y)-a[k].num+1);
}
}
else
{
if(a[k].z==qq)
{
ans=max(ans,zz.checkmx(a[k].y+N-1)-a[k].num+1);
ans=max(ans,nz.checkmx(N-a[k].y)-a[k].num+1);
}
else ans=max(ans,n-a[k].num);
}
}
for(k=i;k<=j;k++)
{
if(a[k].y!=pp)
{
// //cout<<k<<a[k].z;
zy.changemx(a[k].z+N,a[k].num);
ny.changemx(N+1-a[k].z,a[k].num);
}
if(a[k].z!=qq)
{
zz.changemx(a[k].y+N,a[k].num);
nz.changemx(N+1-a[k].y,a[k].num);
}
}
i=j+1;
}
//cout<<endl;

memset(zy.c,0x3f,sizeof(zy.c));
memset(zz.c,0x3f,sizeof(zz.c));
memset(ny.c,0x3f,sizeof(ny.c));
memset(nz.c,0x3f,sizeof(nz.c));
i=1;
while(a[i].x!=o) i++;
j=i;
while(a[j+1].x==a[i].x) j++;
for(k=i;k<=j;k++)
{
if(a[k].y!=p)
{
zy.changemn(a[k].z+N,a[k].num);
ny.changemn(N+1-a[k].z,a[k].num);
}
if(a[k].z!=q)
{
zz.changemn(a[k].y+N,a[k].num);
nz.changemn(N+1-a[k].y,a[k].num);
}
}
i=1;
while(i<=n)
{
j=i;
while(a[j+1].x==a[i].x&&j<n) j++;
if(a[i].x==o){i=j+1;continue;}
for(k=i;k<=j;k++)
{
if(a[k].y==p)
{
ans=max(ans,a[k].num-zy.checkmn(a[k].z+N-1)+1);
ans=max(ans,a[k].num-ny.checkmn(N-a[k].z)+1);
if(a[k].z==q)
{
ans=max(ans,a[k].num-zz.checkmn(a[k].y+N-1)+1);
ans=max(ans,a[k].num-nz.checkmn(N-a[k].y)+1);
}
}
else
{
if(a[k].z==q)
{
ans=max(ans,a[k].num-zz.checkmn(a[k].y+N-1)+1);
ans=max(ans,a[k].num-nz.checkmn(N-a[k].y)+1);
}
else ans=max(ans,a[k].num+1);
}
}
for(k=i;k<=j;k++)
{
if(a[k].y!=p)
{
zy.changemn(a[k].z+N,a[k].num);
ny.changemn(N+1-a[k].z,a[k].num);
}
if(a[k].z!=q)
{
zz.changemn(a[k].y+N,a[k].num);
nz.changemn(N+1-a[k].y,a[k].num);
}
}
i=j+1;
}
ans--;
int tot=0;
char now='7';
for(i=1;i<n;i++)
{
if(s[i]==now) tot++;
else
{
ans=max(ans,tot);
tot=1;
now=s[i];
}
}
ans=max(ans,tot);
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: