题意:有n个球,1~n,n个操作:(a,b),意思是把区间[a,b]里的球都涂一遍色,n次操作后,问每个球分别被涂了多少次。
分析:
区间更新,单点查询。一般区间更新都要用lazy[rt],不然对线段树的更新操作就退化为了暴力更新,会超时。
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=100000; int n; int tot[maxn*4+10],lazy[maxn*4+10]; struct node{ int l,r; }tree[maxn*4+10]; void pushup(int rt) { tot[rt]=tot[rt<<1]+tot[rt<<1|1]; } void pushdown(int rt) { if(lazy[rt]!=0){ if(tree[rt].l==tree[rt].r){ tot[rt]+=lazy[rt]; return; } lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void creat(int l,int r,int rt) { tree[rt].l=l; tree[rt].r=r; lazy[rt]=0; if(l==r){ tot[rt]=0; return; } int mid=(l+r)>>1; creat(l,mid,rt<<1); creat(mid+1,r,rt<<1|1); } void upd(int a,int b,int rt) { if(a<=tree[rt].l&&b>=tree[rt].r){ lazy[rt]+=1; return; } pushdown(rt); int mid=(tree[rt].l+tree[rt].r)>>1; if(a<=mid) upd(a,b,rt<<1); if(b>mid) upd(a,b,rt<<1|1); } void query(int rt) { pushdown(rt); if(tree[rt].l==tree[rt].r){ if(tree[rt].l==1) printf("%d",tot[rt]); else printf(" %d",tot[rt]); return; } query(rt<<1); query(rt<<1|1); } int main() { while(scanf("%d",&n)!=EOF){ if(!n) break; creat(1,n,1); for(int i=0;i<n;i++){ int a,b; scanf("%d%d",&a,&b); upd(a,b,1); } // for(int i=1;i<=20;i++) cout<<lazy[i]<<" "; query(1); printf("\n"); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 1556 给连续个球涂色-线段树-(区间更新,单点查询)
原文地址:http://blog.csdn.net/ac_0_summer/article/details/47729621