cdoj 1061 秋实大哥与战争 线段树,合并区间,单点更新,单点查询区间长度
题目链接:
http://acm.uestc.edu.cn/#/problem/show/1061
题意:
题解:
线段树记录从左边延展的长度,记录从右边延展的长度,和区间最大长度
每次更新的时候,就向上更新
代码:
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,v,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].rm == tree[rt<<1].len) tree[rt].lm = tree[rt<<1].lm+tree[rt<<1|1].lm; 27 if(tree[rt<<1|1].lm == tree[rt<<1|1].len) tree[rt].rm = tree[rt<<1|1].rm+tree[rt<<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 34 if(l != r){ 35 int mid = (l+r)/2; 36 build(rt<<1,l,mid); 37 build(rt<<1|1,mid+1,r); 38 pushup(rt); 39 } 40 } 41 42 void update(int rt,int p,int x){ 43 int L = tree[rt].l, R = tree[rt].r; 44 if(L == R){ 45 tree[rt].lm=tree[rt].rm=tree[rt].mm=x; 46 return ; 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 }else{ 65 if(p<=tree[rt<<1|1].l+tree[rt<<1|1].lm-1) 66 return query(rt<<1|1,p) + query(rt<<1,mid); 67 else 68 return query(rt<<1|1,p); 69 } 70 } 71 72 int main(){ 73 int n=read(),m=read(); 74 build(1,1,n); 75 for(int i=0; i<m; i++){ 76 int op = read(), x = read(); 77 if(op == 0){ 78 update(1,x,0); 79 }else if(op == 1){ 80 update(1,x,1); 81 }else{ 82 ll ans = query(1,x); 83 printf("%lld\n",ans); 84 } 85 } 86 87 return 0; 88 }