3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
1 1 1 3 2 1
思路:就是一道比较水的线段树,非常明显,我用上了懒惰节点。现在做就是为了重温一下线段树,一切都是自己重新码的。
#include<iostream> #include<cstring> #include<cstdio> #define lson t<<1 #define rson t<<1|1 #define midl (l+r)/2 #define midr (l+r)/2+1 using namespace std; const int mm=1e5+9; class node { public:int l,r,lazy,ci; }rt[mm*4]; int n; void build(int t,int l,int r) { rt[t].l=l;rt[t].r=r;rt[t].lazy=rt[t].ci=0; if(l==r)return; build(lson,l,midl);build(rson,midr,r); } void update(int t,int l,int r,int num) { if(rt[t].l==l&&rt[t].r==r){rt[t].ci+=num;rt[t].lazy+=num;return;} rt[lson].lazy+=rt[t].lazy;rt[rson].lazy+=rt[t].lazy; rt[lson].ci+=rt[t].lazy;rt[rson].ci+=rt[t].lazy; rt[t].lazy=0; if(rt[lson].r>=r)update(lson,l,r,rt[t].lazy+num); else if(rt[rson].l<=l)update(rson,l,r,rt[t].lazy+num); else update(lson,l,rt[lson].r,rt[t].lazy+num),update(rson,rt[rson].l,r,rt[t].lazy+num); } int query(int t,int id) { int ret; if(rt[t].l==rt[t].r&&rt[t].l==id)return rt[t].ci; rt[lson].lazy+=rt[t].lazy; rt[lson].ci+=rt[t].lazy; rt[rson].ci+=rt[t].lazy; rt[rson].lazy+=rt[t].lazy; rt[t].lazy=0; if(rt[lson].r>=id)ret=query(lson,id); else ret=query(rson,id); return ret; } int main() { int a,b; while(scanf("%d",&n)&&n) { build(1,1,n); for(int i=0;i<n;++i) { scanf("%d%d",&a,&b); update(1,a,b,1); } printf("%d",query(1,1)); for(int i=2;i<=n;++i) printf(" %d",query(1,i)); printf("\n"); } }