题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:
给你一个区间,有三个操作,使的一个村庄毁灭,使的上一个毁灭的村庄复活,查询这个村庄所在最长区间
题解:
区间合并的线段树,单点修改,记录从左边的最大值,右边的最大值,区间的最大值
然后每次更新
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 1e5+10; 17 18 struct node{ 19 int l,r,lm,rm,mm,len; 20 }tree[maxn<<2]; 21 22 void pushup(int rt){ 23 tree[rt].lm = tree[rt<<1].lm; 24 tree[rt].rm = tree[rt<<1|1].rm; 25 tree[rt].mm = max(max(tree[rt<<1].mm,tree[rt<<1|1].mm),tree[rt<<1].rm+tree[rt<<1|1].lm); 26 if(tree[rt<<1].lm == tree[rt<<1].len) tree[rt].lm = tree[rt<<1].lm + tree[rt<<1|1].lm; 27 if(tree[rt<<1|1].rm == tree[rt<<1|1].len) tree[rt].rm = tree[rt<<1].rm+tree[rt<<1|1].rm; 28 } 29 30 void build(int rt,int l,int r){ 31 tree[rt].l = l, tree[rt].r = r; 32 tree[rt].lm = tree[rt].rm = tree[rt].mm = tree[rt].len = r-l+1; 33 if(l != r){ 34 int mid = (l+r)/2; 35 build(rt<<1,l,mid); 36 build(rt<<1|1,mid+1,r); 37 pushup(rt); 38 } 39 } 40 41 void update(int rt,int p,int x){ 42 int L = tree[rt].l, R = tree[rt].r; 43 if(L == R) { 44 tree[rt].lm=tree[rt].rm=tree[rt].mm = x; 45 return ; 46 } 47 48 int mid = (L+R)/2; 49 if(p <= mid) update(rt<<1,p,x); 50 else update(rt<<1|1,p,x); 51 pushup(rt); 52 } 53 54 ll query(int rt,int p){ 55 int L = tree[rt].l, R = tree[rt].r; 56 if(L==R || tree[rt].mm==0 || tree[rt].mm==tree[rt].len) 57 return tree[rt].mm; 58 int mid = (L+R)/2; 59 if(p<=mid){ 60 if(p >= tree[rt<<1].r - tree[rt<<1].rm + 1){ 61 return query(rt<<1,p) + query(rt<<1|1,mid+1); 62 }else{ 63 return query(rt<<1,p); 64 } 65 }else{ 66 if(p <= tree[rt<<1|1].l+tree[rt<<1|1].lm-1){ 67 return query(rt<<1|1,p) + query(rt<<1,mid); 68 }else{ 69 return query(rt<<1|1,p); 70 } 71 } 72 } 73 74 int main(){ 75 int n,m; 76 while(scanf("%d%d",&n,&m)!=EOF){ 77 stack<int> k; 78 build(1,1,n); 79 for(int i=0; i<m; i++){ 80 char op; scanf(" %c",&op); 81 int t; 82 if(op == 'D'){ 83 scanf("%d",&t); 84 update(1,t,0); 85 k.push(t); 86 }else if(op == 'Q'){ 87 scanf("%d",&t); 88 printf("%I64d ",query(1,t)); 89 }else{ 90 update(1,k.top(),1); 91 k.pop(); 92 } 93 } 94 } 95 96 return 0; 97 }