Segment Game (hdu 5372 树状数组+离散化)

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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-16 11:18:35

Segment Game (hdu 5372 树状数组+离散化)的相关文章

HDU 5372 Segment Game (MUT#7 树状数组+离散化)

[题目链接]:click here~~ [题目大意]: 题意:两种操作,添加线段和删除线段,第i次添加时告诉线段起点并且要添加长度为i的线段,删除第i次添加的线段,问每次添加后有多少线段是落在当前要画的线段内部的. [思路]:比赛的时候居然直接无视了这道题,赛后看了一下,感觉要用到树状数组,有一种前后互相影响的样子,昨天想了一下午,加上昨天晚上,总算是搞明白了,因为每次画的线段的长度是递增的,所以当前画的线段不可能被其他线段包含,那么统计小于左端点的点的个数x和小于等于右端点的点的个数y,两者之

HDU 1394 树状数组+离散化求逆序数

对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们通过树状数组可以明显提高时间效率. 我们可以按照排列的顺序依次将数字放入树状数组中,并依次更新预与之相关联的树状数组元素.那么在将其更新完毕后,我们知道每个数对应的树状数组元素的左边的数肯定比它小,我们在以序列顺序依次更新树状数组时,如果有值在它前面出现,那么它对应的树状数组元素(在这个题目里存放的

hdu 5792 树状数组+离散化+思维

题目大意: Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ada≠b≠c≠d,1≤a<b≤n,1≤c<d≤n,Aa<Ab,Ac>Ad. A1,A2?AnA1,A2?An.  1≤n≤500001≤n≤50000  0≤Ai≤1e9 基本思路: 最朴素的思想就是算出所有顺序对所有逆序对

hdu 3333(树状数组 + 离散化 + hash)

Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3847    Accepted Submission(s): 1306 Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems a

[hdu 4417]树状数组+离散化+离线处理

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 把数字离散化,一个查询拆成两个查询,每次查询一个前缀的和.主要问题是这个数组是静态的,如果带修改操作就不能离线了. //http://acm.hdu.edu.cn/showproblem.php?pid=4417 #include<bits/stdc++.h> using namespace std; const int maxn=100005; int tree[maxn]; int N;

hdu 3015 树状数组+离散化

#include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; struct data { __int64 order; __int64 orign; __int64 rank; }; data heigh[100100], coor[100100]; int cmp(const void *a, const void *b) { return ( (*(data *)a)

Swaps and Inversions HDU - 6318 树状数组+离散化

#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; typedef long long ll; const int N=1e5+10; int a[N]; int ra[N]; int tr[N]; int n,x,y; int sz; int lowbit(int x) { return x&-x; } void

C - The Battle of Chibi HDU - 5542 (树状数组+离散化)

Cao Cao made up a big army and was going to invade the whole South China. Yu Zhou was worried about it. He thought the only way to beat Cao Cao is to have a spy in Cao Cao's army. But all generals and soldiers of Cao Cao were loyal, it's impossible t

hdu4325 树状数组+离散化

http://acm.hdu.edu.cn/showproblem.php?pid=4325 Problem Description As is known to all, the blooming time and duration varies between different kinds of flowers. Now there is a garden planted full of flowers. The gardener wants to know how many flower