因为这题的线段长度是递增的....所以:
题解:对于新插入的线段,查询有多少个线段左端点大于等于该线段的左端点。 再查询有多少个线段的右端点大于该线段右端点, 两者之差就是答案。用两个树状数组搞定。时间复杂度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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDOJ 5372 Segment Game 树状数组+离散化
原文:http://blog.csdn.net/ck_boss/article/details/47452501