zoukankan      html  css  js  c++  java
  • hdu 4288 Coder (线段树+离线)

    题意:

    刚开始有一个空集合。有三种操作:

    1.往集合中加入一个集合中不存在的数 x

    2.从集合中删除一个已经存在的数 x

    3.计算集合的digest sum并输出。       digest sum求法:将集合中所有数从小到大排序,得到a1<a2<...<an。 digest sum = sum(ai) where i mod 5 = 3

    数据范围:

    N ( 1 <= N <= 105 )

    1 <= x <= 109.

    For any “add x” it is guaranteed that x is not currently in the set just before this operation.
    For any “del x” it is guaranteed that x must currently be in the set just before this operation.

    思路:

    先将所有增加过的,删除过的数存下来,去重,搞成线段树。

    每个结点(区间)里有两个东西,一个是 cnt,记录该区间的在集合中的元素的个数。一个是sum[i] , sum[i]:该区间序号%5等于i的存在于集合中的元素的总和。

    插入和删除时维护即可。

    代码:

    int const maxn=1e5+5;
    
    struct node{
        int cnt;
        ll sum[5];
    }tree[maxn<<2];
    
    int n,tot;
    int q[maxn],a[maxn];
    char ope[maxn][15];
    
    void build(int l,int r,int rt){
        tree[rt].cnt=0;
        memset(tree[rt].sum,0,sizeof(tree[rt].sum));
        if(l==r) return;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
    }
    
    void pushUp(int rt){
        rep(i,0,4)
            tree[rt].sum[i]=tree[rt<<1].sum[i]+tree[rt<<1|1].sum[((5-tree[rt<<1].cnt%5)%5+i)%5];
    }
    void update(int k,int pos,int num,int l,int r,int rt){
        tree[rt].cnt+=k;
        if(l==r){
            tree[rt].sum[0]+=(k*num);
            return;
        }
        int m=(l+r)>>1;
        if(pos<=m)
            update(k,pos,num,lson);
        else
            update(k,pos,num,rson);
        pushUp(rt);
    }
    
    int main(){
        //freopen("test.in","r", stdin);
        while(scanf("%d",&n)!=EOF){
            tot=0;
            rep(i,1,n){
                scanf("%s",ope[i]);
                if(ope[i][0]!='s'){
                    scanf("%d",&q[i]);
                    a[tot++]=q[i];
                }
            }
            sort(a,a+tot);
            tot=unique(a,a+tot)-a;
            if(tot==0)
                memset(tree[1].sum,0,sizeof(tree[1].sum));
            else
                build(1,tot,1);
            rep(i,1,n){
                int pos=lower_bound(a,a+tot,q[i])-a+1;
                if(ope[i][0]=='a'){
                    update(1,pos,q[i],1,tot,1);
                    continue;
                }
                if(ope[i][0]=='d'){
                    update(-1,pos,q[i],1,tot,1);
                    continue;
                }
                printf("%I64d
    ",tree[1].sum[2]);
            }
        }
        //fclose(stdin);
    }
  • 相关阅读:
    Linux TCP/IP 连接查看和问题解决
    Linux Tomcat 7.0 管理员登录时"401 Unauthorized" 问题解决方法
    Tomcat 性能监控工具jvisualvm, JConsole
    Tomcat 实战-调优方案
    Linux Tomcat8 访问管理页面 403 Access Denied
    docker redis
    Spring Boot 定时任务
    Nginx rewrite使用
    五 python 发送邮件
    关于注解继承性的一个例子
  • 原文地址:https://www.cnblogs.com/fish7/p/4050006.html
Copyright © 2011-2022 走看看