POJ 2892 线段树(连续问题)

来源:互联网 发布:淘宝售后客服怎么做 编辑:程序博客网 时间:2024/05/22 10:50

题目

Tunnel Warfare
Time Limit: 1000MS Memory Limit: 131072K
Total Submissions: 7496 Accepted: 3093

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 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
Sample Output

1
0
2
4

题意

有几个村庄,D a表示a村庄被摧毁iu,R表示修复上一个村庄,Q a表示包含a的连续村庄有多少个,如果a被摧毁则输出0。

题解

用线段树统计区间内有多少个连续的村长,为了方便表示,用T_L表示这个区间从最右端连续了多少个村庄,用T_R表示这个区间从最左端连续了多少个村庄。那么当一个区间的左儿子整个区间没有被摧毁村庄时,T[t].T_L = T[t<<1].T_L + T[t<<1|1].T_L。右儿子也是一样。那么我们就可以预先把该区间是满的个数算出来,直接判断是不是相等然后就可以合并了。最后查询的时候我们自顶向下寻找,但找到包含这个点的区间时返回。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <set>#include <cmath>#include <stack>#include <map>#include <queue>#include <sstream>#include <vector>#define m0(a) memset(a,0,sizeof(a))#define mm(a) memset(a,0x3f,sizeof(a))#define m_1(a) memset(a,-1,sizeof(a))#define f(i,a,b) for(i = a;i<=b;i++)#define fi(i,a,b) for(i = a;i>=b;i--)#define FFR freopen("data.in","r",stdin)#define FFW freopen("data.out","w",stdout)using namespace std;#define SIZE 50000struct Po{    int T_L,T_R;};Po T[SIZE*4+20];int P[SIZE*4+20];bool p1[SIZE*4+20];bool p2[SIZE*4+20];int NN;void aP(int a,int b){    int t = a+NN;    T[t].T_L = T[t].T_R = b;    for(t>>=1;t;t>>=1){        if(T[t<<1].T_L==P[t<<1])            T[t].T_L = T[t<<1].T_L + T[t<<1|1].T_L;        else            T[t].T_L = T[t<<1].T_L;        if(T[t<<1|1].T_R==P[t<<1|1])            T[t].T_R = T[t<<1].T_R + T[t<<1|1].T_R;        else            T[t].T_R = T[t<<1|1].T_R;    }}int init(int n){    NN = 1;    int i = 0,j;    m0(p1);    m0(p2);    p1[1] = 1;    p2[1] = 1;    while(NN<n){        NN<<=1;        p1[NN] = 1;        p2[NN-1] = 1;        i++;    }    p2[NN*2-1] = 1;    NN--;    int k = i;    int t = 1;    f(i,0,k)        f(j,1,1<<i){            T[t].T_R = T[t].T_L = 1<<(k-i);            P[t++] = 1<<(k-i);        }    f(i,n+1,NN+1)        aP(i,0);}int query(int a,int t,int l,int r){    if(l<=a&&a<=r){        if(a-l+1<=T[t].T_L){            if(!p1[t])                return T[t].T_L+T[t-1].T_R;            else                return T[t].T_L;        }        if(r-a+1<=T[t].T_R){            if(!p2[t])                return T[t].T_R+T[t+1].T_L;            else                return T[t].T_R;        }    }    int m = (l+r)>>1;    if(a<=m) query(a,t<<1,l,m);    else query(a,t<<1|1,m+1,r);}int main(){    ios_base::sync_with_stdio(false); cin.tie(0);    int n,m;    cin>>n>>m;    init(n);    char c;    int a;    int i;    stack<int>st;    f(i,1,m){        cin>>c;        if(c=='D'){            cin>>a;            aP(a,0);            st.push(a);        }        if(c=='R'){            a = st.top();st.pop();            aP(a,1);        }        if(c=='Q'){            cin>>a;            if(T[NN+a].T_L==0)                cout<<"0"<<endl;            else                cout<<query(a,1,1,NN+1)<<endl;        }    }    return 0;}
0 0
原创粉丝点击