Segment Game
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 534 Accepted Submission(s): 132
Problem Description
Lillian is a clever girl so that she has lots of fans and often receives gifts from her fans.
One day Lillian gets some segments from her fans Lawson with lengths of 1,2,3... and she intends to display them by adding them to a number line.At the i-th add operation,she will put the segment with length of i on the number line.Every time she put the segment
on the line,she will count how many entire segments on that segment.During the operation ,she may delete some segments on the line.(Segments are mutually independent)
Input
There are multiple test cases.
The first line of each case contains a integer n — the number of operations(1<=n<=2?105,∑n<=7?105)
Next n lines contain the descriptions of the operatons,one operation per line.Each operation contains two integers a , b.
if a is 0,it means add operation that Lilian put a segment on the position b(|b|<109)
of the line.
(For the i-th add operation,she will put the segment on [b,b+i] of the line, with length of i.)
if a is 1,it means delete operation that Lilian will delete the segment which was added at the b-th add operation.
Output
For i-th case,the first line output the test case number.
Then for each add operation,ouput how many entire segments on the segment which Lillian newly adds.
Sample Input
3 0 0 0 3 0 1 5 0 1 0 0 1 1 0 1 0 0
Sample Output
Case #1: 0 0 0 Case #2: 0 1 0 2 Hint For 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
Source
2015 Multi-University Training Contest 7
Recommend
wange2014 | We have carefully selected several similar problems for you: 5378 5377 5376 5374 5373
题意:两种操作,添加线段和删除线段,第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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。