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
题意:两种操作,添加线段和删除线段,第i次添加时告诉线段起点并且要添加长度为i的线段,删除第i次添加的线段,问每次添加后有多少线段是落在当前要画的线段内部的。
思路:因为每次画的线段的长度是递增的,所以当前画的线段不可能被其他线段包含,那么统计小于左端点的点的个数x和小于等于右端点的点的个数y,ans=y-x。分别用树状数组维护,没写过树状数组了,都忘了,又复习了一下。
代码:
#include <iostream>
#include <functional>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std;
#define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 400005;
const int MAXM = 200010;
const int N = 1005;
typedef pair<int,int>P;
int bit[2][MAXN];
int n;
int pos[MAXN],num;
int L[MAXN],R[MAXN],op[MAXN];
P pir[MAXN];
inline int lowbit(int x)
{
return x&-x;
}
void add(int i,int x,int c) //c=0时表示维护的左端点,c=1时表示维护的右端点
{
while (i<MAXN)
{
bit[c][i]+=x;
i+=lowbit(i);
}
}
int sum(int i,int c)
{
int s=0;
while (i>0)
{
s+=bit[c][i];
i-=lowbit(i);
}
return s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,cas=0;
while (~scanf("%d",&n))
{
int tot=0;num=0;
memset(bit,0,sizeof(bit));
for (i=1;i<=n;i++)
{
scanf("%d%d",&op[i],&L[i]);
if (op[i]==0)
{
R[i]=L[i]+(++tot);
pos[num++]=L[i];
pos[num++]=R[i];
}
}
tot=0;
sort(pos,pos+num);
num=unique(pos,pos+num)-pos;
for (i=1;i<=n;i++) //离散化
{
if (op[i]==0)
{
L[i]=lower_bound(pos,pos+num,L[i])-pos+1;
R[i]=lower_bound(pos,pos+num,R[i])-pos+1;
pir[++tot]=make_pair(L[i],R[i]);
}
}
printf("Case #%d:\n",++cas);
for (i=1;i<=n;i++)
{
if (op[i]==0)
{
printf("%d\n",sum(R[i],1)-sum(L[i]-1,0));
add(L[i],1,0);
add(R[i],1,1);
}
else
{
add(pir[L[i]].first,-1,0);
add(pir[L[i]].second,-1,1);
}
}
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
Segment Game (hdu 5372 树状数组+离散化)
原文:http://blog.csdn.net/u014422052/article/details/47440871