【HDU 5372】Segment Game(树状数组)

来源:互联网 发布:网站建设优化推广 编辑:程序博客网 时间:2024/06/08 13:04

题解:

对于新插入的线段,查询有多少个线段左端点大于等于该线段的左端点。 再查询有多少个线段的右端点大于该线段右端点, 两者之差就是答案。


这里注意两个问题,一个是离散化,第二个这道题时间卡的可能比较严,线段树貌似会超时~


好久没写离散化了。。。生疏了

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000005;int n;//----------------------------------------------------------int Hash[maxn * 2];int Hash_num;int HASH(int u){    return lower_bound(Hash + 1,Hash + Hash_num,u) - Hash;}void Hash_debug(){    for(int i = 1; i < Hash_num; i++)        printf("%d ",Hash[i]);    puts("");}//-----------------------------------------------------------int C[2][maxn];int lowbit(int x){    return  x & (-x);}int sum(int op,int x){    int ret = 0;    while(x > 0){        ret += C[op][x];        x -= lowbit(x);    }    return ret;}void add(int op,int x,int value){    while(x <= Hash_num){        C[op][x] += value;        x += lowbit(x);    }}//-----------------------------------------------------------struct Input{    int op,id,lv;}input[maxn];int pid[maxn];//------------------------------------------------------------int main(){    int Case = 1;    while(scanf("%d",&n) != EOF){        int cnt = 1;        Hash_num = 1;        Hash[Hash_num++] = 0;        memset(C,0,sizeof(C));        for(int i = 0; i < n; i++){            scanf("%d%d",&input[i].op,&input[i].lv);            if(input[i].op == 0){                input[i].lv ++;                Hash[Hash_num++] = input[i].lv;                Hash[Hash_num++] = input[i].lv + cnt;                pid[cnt] = i;                input[i].id = cnt ++;            }        }        sort(Hash + 1,Hash + Hash_num);        Hash_num = unique(Hash + 1,Hash + Hash_num) - Hash;        //Hash_debug();        printf("Case #%d:\n",Case++);        for(int i = 0; i < n; i++){            if(input[i].op == 0){                int sum1 = sum(0,Hash_num);                int sum2 = sum(1,Hash_num);                int lv   = HASH(input[i].lv);                int rv   = HASH(input[i].lv + input[i].id);                int sum11 = sum1 - sum(0,lv - 1);                int sum22 = sum2 - sum(1,rv);                printf("%d\n",abs(sum11 - sum22));                add(0,lv,1);                add(1,rv,1);            }            else{                int id = pid[input[i].lv];                int lv = HASH(input[id].lv);                int rv = HASH(input[id].lv + input[id].id);                add(0,lv,-1);                add(1,rv,-1);            }        }    }    return 0;}


0 0
原创粉丝点击