因为这题的线段长度是递增的....所以:
题解:对于新插入的线段,查询有多少个线段左端点大于等于该线段的左端点。 再查询有多少个线段的右端点大于该线段右端点, 两者之差就是答案。用两个树状数组搞定。时间复杂度nlog
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
/* *********************************************** Author :CKboss Created Time :2015年08月11日 星期二 20时49分58秒 File Name :HDOJ5372.cpp ************************************************ */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <cstdlib> #include <vector> #include <queue> #include <set> #include <map> using namespace std; const int maxn=200200; int n,nx; struct CZ { CZ(){} CZ(int _id,int _kind,int _left,int _right,int _del) { id=_id,kind=_kind,left=_left,right=_right,del=_del; } int id,kind,left,right,del; }cz[maxn]; int caru_left[maxn],caru_right[maxn],cr; int allnum[maxn*3],an; /***********************BIT******************************/ int tree_left[maxn*3],tree_right[maxn*3]; inline int lowbit(int x) { return x&(-x); } void add(int* tree,int p,int v) { for(int i=p;i;i-=lowbit(i)) { tree[i]+=v; } } int sum(int* tree,int p) { int ret=0; for(int i=p;i<an+100;i+=lowbit(i)) { ret+=tree[i]; } return ret; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int cas=1; while(scanf("%d",&n)!=EOF) { an=0; nx=1; cr=1; for(int i=0,kind,val;i<n;i++) { scanf("%d%d",&kind,&val); if(kind==0) { int v1=val; int v2=val+nx; nx++; allnum[an++]=v1; allnum[an++]=v2; cz[i]=CZ(i,0,v1,v2,0); caru_left[cr]=v1; caru_right[cr]=v2; cr++; } else if(kind==1) { cz[i]=CZ(i,1,-999,-999,val); } } sort(allnum,allnum+an); an=unique(allnum,allnum+an)-allnum; //for(int i=0;i<an;i++) cout<<allnum[i]<<","; putchar(10); memset(tree_left,0,sizeof(tree_left)); memset(tree_right,0,sizeof(tree_right)); printf("Case #%d:\n",cas++); for(int i=0;i<n;i++) { CZ cc=cz[i]; if(cc.kind==0) { int l=lower_bound(allnum,allnum+an,cc.left)-allnum+1; int r=lower_bound(allnum,allnum+an,cc.right)-allnum+1; int s1=sum(tree_left,l); int s2=sum(tree_right,r+1); printf("%d\n",s1-s2); add(tree_left,l,1); add(tree_right,r,1); } else if(cc.kind==1) { cc.left=caru_left[cc.del]; cc.right=caru_right[cc.del]; int l=lower_bound(allnum,allnum+an,cc.left)-allnum+1; int r=lower_bound(allnum,allnum+an,cc.right)-allnum+1; add(tree_left,l,-1); add(tree_right,r,-1); } } } return 0; }