• HDU 5372 Segment Game


    /**
    多校联合2015-muti7-1004
    <a target=_blank href="http://acm.hdu.edu.cn/showproblem.php?pid=5372">HDU 5372 Segment Game
    <span style="font-family: Arial, Helvetica, sans-serif;"></span><span style="font-family: Arial, Helvetica, sans-serif;"></a></span>
    树状数组
    */
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 400005
    #define ll __int64
    using namespace std;
    int cl[maxn],cr[maxn];
    int a[maxn],b[maxn];
    int op[maxn];
    int dis[maxn],cor;
    int n;
    void insert(int c[],int i,int val){
      //  cout<<n<<endl;
        while(i<=cor){
            c[i]+=val;
            i+=(i&(-i));
        }
    }
    int query_sum(int c[],int i){
        int s=0;
        while(i>0){
            s+=c[i];
            i-=(i&(-i));
        }
        return s;
    }
    int query(int c[],int last){
        if(last>cor) return 0;
        return query_sum(c,cor)-query_sum(c,last-1);
    }
    void Init(){
        memset(cl,0,sizeof(cl));
        memset(cr,0,sizeof(cr));
        cor=0;
    }
    void disc(){ //离散化数组去重
        sort(dis,dis+cor);
        int t=0;
        for(int i=1;i<cor;i++){
            if(dis[i]==dis[i-1]) t++;
            else dis[i-t]=dis[i];
        }
        cor-=t;
    }
    int index(int num){//返回离散值
        return lower_bound(dis,dis+cor,num)-dis+1;
    }
    int main(){
        int ii=1;
        while(~scanf("%d",&n)){
            printf("Case #%d:
    ",ii++);
            Init();
            int l,r,A=1;
            for(int i=0;i<n;i++){
                scanf("%d%d",&a[i],&b[i]);
                if(a[i]==0){
                    dis[cor++]=b[i];
                    dis[cor++]=b[i]+A;
                    A++;
                }
            }
            disc();
            A=1;
            int ans=0;
            for(int i=0;i<n;i++){
                if(a[i]==0){
                    l=index(b[i]);
                    r=index(b[i]+A);
                    //左端点及阻断点后的左端点与右端点后的右端点之差即为所求
                    ans=(query(cl,l)-query(cr,r+1));
                    printf("%d
    ",ans);
                    insert(cl,l,1);
                    insert(cr,r,1);
                    op[A]=b[i];
                    A++;
                }
                else{
                    l=index(op[b[i]]);
                    r=index(op[b[i]]+b[i]);
                    insert(cl,l,-1);
                    insert(cr,r,-1);
                }
            }
        }
        return 0;
    }
    

  • 相关阅读:
    过河问题 (Standard IO)
    单词分类 (Standard IO)
    C#综合揭秘——细说多线程(上)
    使用NPOI导入导出标准Excel
    C# 转义字符 ''反斜杠
    ref和out的区别
    抽象类接口的区别
    方法签名
    SQL Server的通用分页存储过程 未使用游标,速度更快!
    SQL Server存储过程Return、output参数及使用技巧
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6908778.html
Copyright © 2020-2023  润新知