3 0 0 0 3 0 1 5 0 1 0 0 1 1 0 1 0 0
Case #1: 0 0 0 Case #2: 0 1 0 2HintFor the second case in the sample: At the first add operation,Lillian adds a segment [1,2] on the line. At the second add operation,Lillian adds a segment [0,2] on the line. At the delete operation,Lillian deletes a segment which added at the first add operation. At the third add operation,Lillian adds a segment [1,4] on the line. At the fourth add operation,Lillian adds a segment [0,4] on the line
先离散化
然后由于长度是递增的。两个树状数组分别记录,起点和终点的个数。
那么加入线段时l,r(起始,终止位置), <= r的终止个数 - < l 的起始位置就是答案了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<vector> using namespace std; #define maxn 400007 void add(int *tree,int p,int n){ while(p < maxn){ tree[p] += n; p += (p&(-p)); } } int query(int *tree,int p){ int ans = 0; while(p > 0){ ans += tree[p]; p -= (p&(-p)); } return ans; } int w[maxn],ls[maxn],rs[maxn]; int num[maxn]; int en[maxn],be[maxn]; vector<int> seg; map<int,int>haha; int main(){ int n,tt=1; //freopen("1004.in","r",stdin); //freopen("1004x.out","w",stdout); while(scanf("%d",&n) != EOF){ haha.clear(); seg.clear(); memset(be,0,sizeof(be)); memset(en,0,sizeof(en)); int ty,p; for(int i = 0;i < n; i++){ scanf("%d%d",&ty,&p); if(ty == 0){ w[i] = 1; ls[i] = p; rs[i] = p+seg.size()+1; haha[p] = 0; haha[p+seg.size()+1] = 0; seg.push_back(i); } else { p = seg[p-1]; w[i] = -1; ls[i] = ls[p]; rs[i] = rs[p]; } } int cnt = 2; map<int,int>::iterator it = haha.begin(); while(it != haha.end()){ it->second = cnt++; it++; } for(int i = 0;i < n; i++){ ls[i] = haha[ls[i]]; rs[i] = haha[rs[i]]; } printf("Case #%d:\n",tt++); for(int i = 0;i < n; i++){ if(w[i] == 1){ printf("%d\n",query(en,rs[i]) - query(be,ls[i]-1) ); add(en,rs[i],1); add(be,ls[i],1); } else { add(en,rs[i],-1); add(be,ls[i],-1); } } } return 0; }