HDU1540(Tunnel Warfare)
题目链接:传送门
题目大意:有n个村庄,m个操作。操作有三种。1.'D x' 摧毁村庄x,2.'R' 把最后摧毁的村庄重建,3.'Q x'问与x相连的村庄有多少个
题目思路:线段树区间合并
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include <set> #include <map> #include <climits> #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define fi first #define se second #define ping(x,y) ((x-y)*(x-y)) #define mst(x,y) memset(x,y,sizeof(x)) #define mcp(x,y) memcpy(x,y,sizeof(y)) using namespace std; #define gamma 0.5772156649015328606065120 #define MOD 1000000007 #define inf 0x3f3f3f3f #define N 500005 #define maxn 50005 typedef pair<int,int> PII; typedef long long LL; const double pi=acos(-1.0); const double e=2.718281828459; stack<int>sk; int n,m,x; char str[10]; int node[maxn<<2],mark[maxn<<2]; int lsum[maxn<<2],rsum[maxn<<2]; inline void pushup(int root,int l,int r,int mid){ lsum[root]=lsum[root<<1]; rsum[root]=rsum[root<<1|1]; node[root]=max(max(node[root<<1],node[root<<1|1]),rsum[root<<1]+lsum[root<<1|1]); if(lsum[root]==mid-l+1) lsum[root]+=lsum[root<<1|1]; if(rsum[root]==r-mid) rsum[root]+=rsum[root<<1]; } void build(int root,int l,int r){ if(l==r){ node[root]=lsum[root]=rsum[root]=1; return; } int mid=l+r>>1; build(lson);build(rson); pushup(root,l,r,mid); } void add(int root,int l,int r,int flag){ if(l==r){ if(flag==1) lsum[root]=rsum[root]=node[root]=1; else lsum[root]=rsum[root]=node[root]=0; return; } int mid=l+r>>1; if(x<=mid) add(lson,flag); else add(rson,flag); pushup(root,l,r,mid); } int query(int root,int l,int r,int x){ if(l==r||node[root]==(r-l+1)||node[root]==0){ return node[root]; } int mid=l+r>>1; if(x<=mid){ if(x>mid-rsum[root<<1])return query(lson,x)+query(rson,mid+1); else return query(lson,x); } else{ if(x<lsum[root<<1|1]+mid+1)return query(lson,mid)+query(rson,x); else return query(rson,x); } } int main(){ int i,j; while(scanf("%d%d",&n,&m)!=EOF){ while(!sk.empty()){sk.pop();} build(1,1,n); while(m--){ scanf("%s",str); if(str[0]=='D'){ scanf("%d",&x); sk.push(x); add(1,1,n,-1); } else if(str[0]=='Q'){ scanf("%d",&x); printf("%d\n",query(1,1,n,x)); } else{ if(!sk.empty()){ x=sk.top(); sk.pop(); add(1,1,n,1); } } } } return 0; }