题目大意:。。。不是很好叙述自己看吧。注意要剪掉初始就能到达所有终点的点的数量
http://blog.163.com/c_sunshine/blog/static/2439650542015028013488/
OTZ 这做法实在是太优雅了!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 100100
using namespace std;
struct abcd{
int pos,val;
abcd() {}
abcd(int _,int __):
pos(_),val(__) {}
}a1[M],a2[M];
int tot1,tot2;
int n,m,p,k,ans;
int l[M],r[M];
bool Compare1(const abcd &x,const abcd &y)
{
if( x.pos != y.pos )
return x.pos < y.pos ;
return x.val < y.val ;
}
bool Compare2(const abcd &x,const abcd &y)
{
if( x.pos != y.pos )
return x.pos > y.pos ;
return x.val < y.val ;
}
struct BIT{
int c[M];
void Update(int x,int y)
{
for(;x;x-=x&-x)
c[x]=max(c[x],y);
}
int Get_Ans(int x)
{
int re=0;
for(;x<=m;x+=x&-x)
re=max(re,c[x]);
return re;
}
}b1,b2;
int main()
{
int i,j,x,y,z;
cin>>n>>m>>p>>k;++m;
for(i=1;i<=p;i++)
{
scanf("%d%d%d",&x,&y,&z);++y;
if(z)
new (&a1[++tot1])abcd(x+1,y);
else
new (&a2[++tot2])abcd(x,y);
}
sort(a1+1,a1+tot1+1,Compare1);
sort(a2+1,a2+tot2+1,Compare2);
l[0]=r[n+1]=-1;
for(j=1,i=1;i<=n;i++)
{
l[i]=l[i-1]+1;
for(;j<=tot1&&a1[j].pos==i;j++)
{
int temp=b1.Get_Ans(a1[j].val)+1;
l[i]=min(l[i],(i-1)-temp);
b1.Update(a1[j].val,temp);
}
}
for(j=1,i=n;i;i--)
{
r[i]=r[i+1]+1;
for(;j<=tot2&&a2[j].pos==i;j++)
{
int temp=b2.Get_Ans(a2[j].val)+1;
r[i]=min(r[i],(n-i)-temp);
b2.Update(a2[j].val,temp);
}
}
for(j=1,i=1;i<=n;i++)
{
for(;i-j+1&&l[i]+r[j]>k;j++);
ans=max(ans,i-j+1);
}
for(i=1;i<=n;i++)
if(!l[i]&&!r[i])
--ans;
cout<<ans<<endl;
return 0;
}