HDU 1540 Tunnel Warfare

来源:互联网 发布:黑人假发 知乎 编辑:程序博客网 时间:2024/06/05 02:22

题意给出一个连续的数列。共n个,m个操作。

D x 表示把x-th的村庄摧毁。

Q x 表示加上x-th在内的连续村庄有多少个。

R 表示把上次摧毁的村庄恢复。


开始是想用线段树写的,可是各种没思路,不知道每次查询的时候怎么弄。

然后看大神题解。了解设置 l,r,m 分别代表左边连续区间,右边连续区间,当前连续区间。

区间进行合并操作。

#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<bitset>#include<vector>#include<cmath>#define INF 0x7fffffff#define eps 1e-8#define LL long long#define PI 3.141592654#define CLR(a,b) memset(a,b,sizeof(a))#define FOR(i,a,b) for(int i=a;i<b;i++)#define FOR_(i,a,b) for(int i=a;i>=b;i--)#define sf scanf#define pf printf#define all(v) (v).begin(),(v).end()#define acfun std::ios::sync_with_stdio(false)#define SIZE (50000 +2)#define MOD 1000000007using namespace std;struct node{    int ln,mn,rn;}a[SIZE*4];void build(int l,int r,int o){    a[o].ln=a[o].rn=a[o].mn=(r-l+1);    if(l==r)return;    int m=(l+r)>>1;    build(l,m,o*2);    build(m+1,r,o*2+1);}void update(int l,int r,int o,int t,bool re){    if(l==r)    {        if(re)            a[o].ln=a[o].rn=a[o].mn=1;        else            a[o].ln=a[o].rn=a[o].mn=0;    }    else    {        int m=(l+r)>>1;        if(t<=m)update(l,m,o*2,t,re);        else update(m+1,r,o*2+1,t,re);        a[o].ln=a[o*2].ln;        a[o].rn=a[o*2+1].rn;        a[o].mn=max(max(a[o*2].mn,a[o*2+1].mn),a[o*2].rn+a[o*2+1].ln);        if(a[o*2].ln==m-l+1)a[o].ln+=a[o*2+1].ln;        if(a[o*2+1].rn==r-m)a[o].rn+=a[o*2].rn;    }}int query(int l,int r,int o,int t){    if(l==r||a[o].mn==0||a[o].mn==r-l+1)        return a[o].mn;    int m=(l+r)>>1;    if(t<=m)    {        if(t>=m-a[o*2].rn+1)            return query(l,m,o*2,t)+query(m+1,r,o*2+1,m+1);        else            return query(l,m,o*2,t);    }    else    {        if(t<=m+1+a[o*2+1].ln-1)            return query(m+1,r,o*2+1,t)+query(l,m,o*2,m);        else            return query(m+1,r,o*2+1,t);    }}int main(){    int n,m;    while(~sf("%d%d",&n,&m))    {        build(1,n,1);        stack<int>s;        while(m--)        {            int x;            getchar();            int ch=getchar();            if(ch=='D')            {                sf("%d",&x);                s.push(x);                update(1,n,1,x,0);            }            else if(ch=='Q')            {                sf("%d",&x);                int tmp=query(1,n,1,x);                pf("%d\n",tmp);            }            else if(ch=='R')            {                if(!s.empty())                {                    x=s.top();                    s.pop();                    update(1,n,1,x,1);                }            }        }    }}



0 0
原创粉丝点击