线段树 区间合并 成段更新题,什么鬼,模拟它,不断地成段更新,最后好不容易调试出来了,发现TLE,而且只超了80ms,什么鬼!!!
然后小小地优化了一下,如果前面的一些区间被最后的一个区间完全覆盖的话,就没必要更新它。小小的优化了一下,就过了,是飘过。。。。
前前后后搞了3个小时吧。
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 1000005;
int lsum[maxn<<2] , rsum[maxn<<2] , msum[maxn<<2],ln[maxn<<2],rn[maxn<<2];
int cover[maxn<<2];
int x[maxn],y[maxn],ansx[maxn],ansy[maxn];
int cnt=0;
struct node
{
int x,y;
}a[100005],ans[100005];
void PushDown(int rt,int m)
{
if (cover[rt] != -1)
{
cover[rt<<1] = cover[rt<<1|1] = cover[rt];
ln[rt<<1]=rn[rt<<1]=cover[rt];
ln[rt<<1|1]=rn[rt<<1|1]=cover[rt];
msum[rt<<1] = lsum[rt<<1] = rsum[rt<<1] =m - (m >> 1);
msum[rt<<1|1] = lsum[rt<<1|1] = rsum[rt<<1|1] = (m >> 1);
//printf("%d: rt lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]);
//printf("%d: lson lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt<<1],rsum[rt<<1],msum[rt<<1],ln[rt<<1],rn[rt<<1],cover[rt<<1]);
// printf("%d: rson lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,lsum[rt<<1|1],rsum[rt<<1|1],msum[rt<<1|1],ln[rt<<1|1],rn[rt<<1|1],cover[rt<<1|1]);
cover[rt] = -1;
}
}
void PushUp(int rt,int m)
{
lsum[rt] = lsum[rt<<1];rsum[rt] = rsum[rt<<1|1];
msum[rt] = max(msum[rt<<1],msum[rt<<1|1]);
ln[rt]=ln[rt<<1];rn[rt]=rn[rt<<1|1];
if(rn[rt<<1]==ln[rt<<1|1]&&rn[rt<<1]&&ln[rt<<1|1])
{
if (lsum[rt] == m - (m >> 1)) lsum[rt] += lsum[rt<<1|1];
if (rsum[rt] == (m >> 1)) rsum[rt] += rsum[rt<<1];
msum[rt] = max(lsum[rt<<1|1] + rsum[rt<<1] , msum[rt]);
}
}
void build(int l,int r,int rt)
{
msum[rt] = lsum[rt] = rsum[rt] = 0;//r - l + 1;
ln[rt]=rn[rt]=0;
cover[rt] = -1;
if (l == r) return ;
int m = (l + r) >> 1;
build(lson);
build(rson);
}
void update(int L,int R,int c,int l,int r,int rt)
{
if (L <= l && r <= R)
{
msum[rt] = lsum[rt] = rsum[rt] = r - l + 1;
cover[rt] = c;
ln[rt]=rn[rt]=c;
//printf("%d: [%d %d] lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,l,r,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]);
return ;
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (m < R) update(L , R , c , rson);
PushUp(rt , r - l + 1);
//printf("%d: [%d %d] lsum=%d rsum=%d msum=%d ln=%d rn=%d cover=%d\n",cnt++,l,r,lsum[rt],rsum[rt],msum[rt],ln[rt],rn[rt],cover[rt]);
}
int Scan()
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
int main()
{
int n , m;
//freopen("in.txt","r",stdin);
//while(n=Scan())
while(~scanf("%d%d",&n,&m))
{
//m=Scan();
build(1 , n , 1);
for(int i=1;i<=m;i++) scanf("%d%d",&a[i].x,&a[i].y);
int p=1,l=a[m].x,r=a[m].y;
if(m) ans[p++]=a[m];
for(int i=m;i>=1;i--)
if(a[i].x<=l||a[i].y>=r) ans[p++]=a[i];
for(int i=p-1,id=1;i>=1;i--)
{
//printf("update[%d,%d]\n",ans[i].x,ans[i].y);
update(ans[i].x,ans[i].y,id++,1,n,1);
}
//puts("yes");
printf("%d\n",msum[1]);
}
return 0;
}