hdu-154-Tunnel Warfare(线段树,区间)

来源:互联网 发布:xy苹果助手for mac 编辑:程序博客网 时间:2024/06/05 17:12

Problem Description
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.

Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!
 

Input
The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event. There are three different events described in different format shown below: D x: The x-th village was destroyed. Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself. R: The village destroyed last was rebuilt.
 

Output
Output the answer to each of the Army commanders’ request in order on a separate line.
 

Sample Input
7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4
 

Sample Output
1024

与题目: poj-3368-Frequent values-(线段树)非常之相似

题目给出一个区间,有三种操作D:破坏一个点,Q:查询与该点相连的点的个数,R:修复最后破坏的点

用线段树存放3个值,num是当前区间内连续最多的数,lnum记录区间最左边的连续长度,r记录区间最右边的连续长度,

AC代码:

#include<iostream>#include<string>#include<cstdio>#include<algorithm>#include<cmath>#include<iomanip>#include<queue>#include<cstring>#include<map>using namespace std;typedef long long ll;#define M 50010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n,m;struct node{    int l,r,num,lnum,rnum;}tree[M<<2];int p[M]; //记录摧毁情况inline void pushup(int rt){    int temp=tree[rt<<1].rnum+tree[rt<<1|1].lnum;    tree[rt].num=max(max(tree[rt<<1].num,tree[rt<<1|1].num),temp); //父区间最大连续长度为,两个子区间中的最大连续连续或者为将两个子区间连接后中间的连续长度    tree[rt].lnum=tree[rt<<1].lnum; //一般父区间最左边的连续长度等于左子区间最左边的连续长度    if(tree[rt<<1].lnum==(tree[rt<<1].r-tree[rt<<1].l+1)) //但是如果合并上右子区间后生成新的最大连续,则加上新连接的    {        tree[rt].lnum+=tree[rt<<1|1].lnum;    }    tree[rt].rnum=tree[rt<<1|1].rnum;    if(tree[rt<<1|1].rnum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))    {        tree[rt].rnum+=tree[rt<<1].rnum;    }}void build(int l,int r,int rt) //建树{    tree[rt].l=l;    tree[rt].r=r;    tree[rt].num=tree[rt].lnum=tree[rt].rnum=r-l+1;    if(l==r)    {        return;    }    int m=(l+r)>>1;    build(lson);    build(rson);}void update(int x,int v,int rt) //x是位置,rt是线段树标记,v说明修还是毁{    if(tree[rt].l==tree[rt].r)    {        tree[rt].num=tree[rt].lnum=tree[rt].rnum=v;        return;    }    int m=(tree[rt].l+tree[rt].r)>>1;    if(x<=m)        update(x,v,rt<<1);    else        update(x,v,rt<<1|1);    pushup(rt); //由子区间更新父区间}int query(int x,int rt){    if(tree[rt].l==tree[rt].r||tree[rt].num==0||tree[rt].num==(tree[rt].r-tree[rt].l+1)) //到达叶节点或者全被毁或者全没毁就返回    {        return tree[rt].num;    }    int m=(tree[rt].l+tree[rt].r)>>1;    if(x<=m) //x在左子树    {        if(x>=tree[rt<<1].r-tree[rt<<1].rnum+1) //但是x在左子树最右边一个连续区间的范围内        {            return query(x,rt<<1)+query(m+1,rt<<1|1); //那么加上x在右子树的连续值,就是右子树最左边的连续值        }        else        {            return query(x,rt<<1); //否则x最多在左子树内有连续区间,但是x连续不到右子树        }    }    else    {        if(x<=tree[rt<<1|1].lnum+tree[rt<<1|1].l-1)        {            return query(x,rt<<1|1)+query(m,rt<<1);        }        else        {            return query(x,rt<<1|1);        }    }}int main(){    int x=0,top;    char ch[2];    while(scanf("%d%d",&n,&m)!=EOF)    {        top=0;        build(1,n,1);        while(m--)        {            scanf("%s",ch);            if(ch[0]=='D')            {                scanf("%d",&x);                p[top++]=x;                update(x,0,1); //毁掉x            }            else if(ch[0]=='Q')            {                scanf("%d",&x);                printf("%d\n",query(x,1));            }            else            {                if(top>0)                {                    x=p[--top];                    update(x,1,1); //修复x                }            }        }    }    return 0;}



阅读全文
0 0