2015 UESTC 数据结构专题D题 秋实大哥与战争 变化版本的线段树,合并区间,单点查询

D - 秋实大哥与战争

Time Limit: 1 Sec  Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/contest/show/59

Description

男儿何不带吴钩,收取关山五十州。

征战天下是秋实大哥一生的梦想,所以今天他又在练习一个对战游戏。

秋实大哥命令所有士兵从左到右排成了一行来抵挡敌人的攻击。

敌方每一次会攻击一个士兵,这个士兵就会阵亡,整个阵列就会从这个位置断开;同时有的时候已阵亡的士兵会受人赢气息感染而复活。

秋实大哥想知道某一时刻某一个士兵所在的阵列的长度是多少。

Input

第一行包含两个整数n,m,表示秋实大哥的士兵数目和接下来发生的事件数目。

接下来m行,每一行是以下三种事件之一:

0 x : 表示x位置的士兵受到攻击阵亡
1 x : 表示x位置的士兵受人赢气息感染复活
2 x : 秋实大哥想知道第x个士兵所在阵列的长度

1≤n,m≤100000,1≤x≤n。

Output

对于每一个2 x事件,输出对应的答案占一行。
 

Sample Input

5 3
2 2
0 3
2 2

Sample Output

5
2

HINT


题意


题解:

set或者线段树都行,线段树记录从左边延展的长度,记录从右边延展的长度,和区间最大长度
每次更新的时候,就向上更新

代码:

 

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 150001
#define mod 10007
#define eps 1e-9
//const int inf=0x7fffffff;   //无限大
const int inf=0x3f3f3f3f;
/*

int buf[10];
inline void write(int i) {
  int p = 0;if(i == 0) p++;
  else while(i) {buf[p++] = i % 10;i /= 10;}
  for(int j = p-1; j >=0; j--) putchar('0' + buf[j]);
  printf("\n");
}
*/
//**************************************************************************************
inline ll read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

struct node
{
    int l,r;
    int len;
    int lm,rm,mm;
};
node a[maxn*4];

void build(int l,int r,int x)
{
    a[x].l=l,a[x].r=r;
    a[x].lm=a[x].rm=a[x].len=a[x].mm=r-l+1;
    if(l!=r)
    {
        int mid=(l+r)>>1;
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
    }
}
void updata(int i,int t,int x)
{
    if(a[i].l == a[i].r)
    {
        a[i].lm = a[i].rm = a[i].mm = x;
        return ;
    }
    int mid = (a[i].l+a[i].r)>>1;
    if(t<=mid)
        updata(2*i,t,x);
    else
        updata(2*i+1,t,x);
    a[i].lm = a[2*i].lm;
    a[i].rm = a[2*i+1].rm;
    a[i].mm = max(max(a[2*i].mm,a[2*i+1].mm),a[2*i].rm+a[2*i+1].lm);
    if(a[2*i].lm == a[2*i].r-a[2*i].l+1)
        a[i].lm += a[2*i+1].lm;
    if(a[2*i+1].rm == a[2*i+1].r-a[2*i+1].l+1)
        a[i].rm += a[2*i].rm;
}
int query(int x,int p)
{
    if(a[x].l==a[x].r||a[x].mm==0||a[x].mm==a[x].len)
        return a[x].mm;
    int mid=(a[x].l+a[x].r)>>1;
    if(p<=mid)
    {
        if(p>=a[x<<1].r-a[x<<1].rm+1)
            return query(x<<1,p)+query(x<<1|1,mid+1);
        else
            return query(x<<1,p);
    }
    else
    {
        if(p<=a[x<<1|1].l+a[x<<1|1].lm-1)
            return query(x<<1|1,p)+query(x<<1,mid);
        else
            return query(x<<1|1,p);
    }
}

int main()
{
    int n,m,x,y;
    n=read(),m=read();
    build(1,n,1);
    for(int i=0;i<m;i++)
    {
        x=read(),y=read();
        if(x==0)
            updata(1,y,0);
        if(x==1)
            updata(1,y,1);
        if(x==2)
            printf("%d\n",query(1,y));
    }
}

 

posted @ 2015-04-14 22:54  qscqesze  阅读(276)  评论(0编辑  收藏  举报