标签:one inpu res orm 应该 fine upd panel lin
InputThe 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.
OutputOutput 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
表示初识线段树,对区间维护前缀后缀表示无力,不过最后还是卡过去了。注释应该比较清晰。。。
清楚线段树的结构,和区间前缀后缀 左孩子右孩子的拼接情况。。。说不清楚。。。。
1 #include <iostream> 2 #include <stdio.h> 3 #include <math.h> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <string> 7 #include <vector> 8 #include <set> 9 #include <map> 10 #include <queue> 11 #include <algorithm> 12 #include <sstream> 13 #include <stack> 14 using namespace std; 15 #define FO freopen("in.txt","r",stdin); 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define pb push_back 19 #define mp make_pair 20 #define all(x) (x).begin(),(x).end() 21 #define fi first 22 #define se second 23 #define SZ(x) ((int)(x).size()) 24 #define debug(x) cout << "&&" << x << "&&" << endl; 25 #define lowbit(x) (x&-x) 26 #define mem(a,b) memset(a, b, sizeof(a)); 27 typedef vector<int> VI; 28 typedef long long ll; 29 typedef pair<int,int> PII; 30 const ll mod=1000000007; 31 const int inf = 0x3f3f3f3f; 32 ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} 33 ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} 34 //head 35 36 const int maxn=50010; 37 int pre[maxn<<2],suf[maxn<<2],maxx[maxn<<2],n,m,st[maxn];//维护区间前缀1,区间后缀1,st模拟栈 38 39 void pushup(int rt,int x) { 40 pre[rt]=pre[rt<<1];//rt的前缀1就是左孩子前缀1 41 suf[rt]=suf[rt<<1|1];//rt后缀1就是右孩子后缀1 42 maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);//rt的最大两种情况 43 maxx[rt]=max(maxx[rt],pre[rt<<1|1]+suf[rt<<1]); 44 if(suf[rt<<1|1]==(x>>1)) suf[rt]+=suf[rt<<1];// 如果右孩子的后缀全是1,可以拼接左孩子的后缀 45 if(pre[rt<<1]==(x-(x>>1))) pre[rt]+=pre[rt<<1|1];//如果左孩子前缀全是1 可以拼接右孩子的前缀 46 } 47 48 void build(int rt,int L,int R) { 49 pre[rt]=suf[rt]=maxx[rt]=R-L+1;//这里置为R-L+1 和 常规用pushup效果一样 50 int mid=(L+R)>>1; 51 if(L!=R) { 52 build(rt<<1,L,mid); 53 build(rt<<1|1,mid+1,R); 54 } 55 } 56 57 void updata(int rt,int L,int R,int pos,int val) { 58 if(L==R) {//单点修改 59 pre[rt]=suf[rt]=maxx[rt]=val; 60 return; 61 } 62 int mid=(L+R)>>1; 63 if(pos<=mid) updata(rt<<1,L,mid,pos,val); 64 else updata(rt<<1|1,mid+1,R,pos,val); 65 pushup(rt,R-L+1); 66 } 67 68 int query(int rt,int L,int R,int pos) { 69 if(L==R||maxx[rt]==0||maxx[rt]==(R-L+1))//断点 || maxx为0 || maxx最大 70 return maxx[rt]; 71 int mid=(L+R)>>1; 72 if(pos<=mid) {//如果在左子树 73 if(pos>=mid-suf[rt<<1]+1) return pre[rt<<1|1]+suf[rt<<1];//如果大于左孩子的后缀1 == 包含两部分 74 else return query(rt<<1,L,mid,pos); //否则搜左子树 75 } else {//如果在右子树 76 if(pos<=mid+1+pre[rt<<1|1]-1) return pre[rt<<1|1]+suf[rt<<1];//如果小于右孩子的前缀1 == 包含两部分 77 else return query(rt<<1|1,mid+1,R,pos);//否则右子树 78 } 79 } 80 81 int main() { 82 while(~scanf("%d%d",&n,&m)) { 83 int cur=0; 84 build(1,1,n); 85 int pos; 86 while(m--) { 87 char s[3]; 88 scanf("%s",s); 89 if(s[0]==‘D‘) { 90 scanf("%d",&pos); 91 st[cur++]=pos; 92 updata(1,1,n,pos,0); 93 } else if(s[0]==‘Q‘) { 94 scanf("%d",&pos); 95 printf("%d\n",query(1,1,n,pos)); 96 } else { 97 pos=st[--cur]; 98 updata(1,1,n,pos,1); 99 } 100 } 101 } 102 }
kuangbin专题七 HDU1540 Tunnel Warfare (前缀后缀线段树)
标签:one inpu res orm 应该 fine upd panel lin
原文地址:https://www.cnblogs.com/ACMerszl/p/9886650.html