zoukankan      html  css  js  c++  java
  • hdu 4288 线段树 (离散化的离线算法)

    输入描述:

    输入第一行有一个n 表示接下来有n个命令

    接下来的每一行包括一个修改命令 包括一个  字符串命令和一个整数   或者一个求和命令:

      ( 其意思为:  add x  将x插入的数组中,del x 从数组中删除,保持数组有序,保证不插入重复的不删除不存在的

        sum 命令表示输出数组中顺序%5==3 的所有元素之和 )

    输出描述: 输出每一个sum命令的结果

    输入样例:

    9

    add 1
    add 2
    add 3
    add 4
    add 5
    sum
    add 6
    del 3
    sum

    输出样例:

    3

    4

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define MAXN 100005
    struct Seg{
        int lift,right;
        int num;
        long long sum[5];//存放每一段区间中顺序%5的各个值之和
        void init_seg(int l,int r){
            lift=l,right=r,num=0,memset(sum,0,sizeof(sum));
        }
    } T[MAXN<<2];
    char cmd[MAXN];
    int x[MAXN];
    int ans[MAXN];
    void pushup(int i){//向上修改sum值
        int t1=(i<<1)+1,t2=t1+1;
        for(int j=0; j<5; j++)
            T[i].sum[j]=T[t1].sum[j];
        for(int j=T[t1].num%5,k=0; k<5; k++,j++)
            T[i].sum[j%5]+=T[t2].sum[k];
    }
    void build(int i,int l,int r){
        T[i].init_seg(l,r);
        if(l==r)
            return;
        build((i<<1)+1,l,((l+r)>>1));
        build((i+1)<<1,((l+r)>>1)+1,r);
    }
    int key,add_del;//add_del==1 添加一个数 add_del==-1删除一个数
    void update(int i){
        if(T[i].lift==T[i].right){
            T[i].num^=1;
            T[i].sum[0]= add_del==1 ? key : 0;
            return;
        }
        if(ans[(T[i].lift+T[i].right)>>1] >= key)
            update((i<<1)+1);
        else
            update((i+1)<<1);
        T[i].num+=add_del;
        pushup(i);
    }
    int main(){
        int n,top;
        char ch[10];
        while(~scanf("%d",&n)){
            for(int i=top=0; i<n; i++){
                scanf("%s",ch);
                cmd[i]=ch[0];
                if(ch[0]!='s')
                    scanf("%d",&x[top]),ans[top]=x[top++];
            }
            sort(ans,ans+top);
            build(0,0,unique(ans,ans+top)-ans-1);
            for(int i=0,j=0; i<n; i++){
                if(cmd[i]=='s'){
                    printf("%I64d\n",T[0].sum[2]);
                    continue;
                }
                key=x[j++];
                add_del= cmd[i]=='a' ? 1 : -1;
                update(0);
            }
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 3684 大朋友和多叉树
    Loj #2495. 「AHOI / HNOI2018」转盘
    Loj #2494. 「AHOI / HNOI2018」寻宝游戏
    Loj 2320.「清华集训 2017」生成树计数
    SQL Server 权限管理
    微信和支付宝支付模式详解及实现(.Net标准库)- OSS开源系列
    跨站请求伪造(CSRF)
    require.js入门
    C#中禁止跨线程直接访问控件
    Video.js web视频播放器
  • 原文地址:https://www.cnblogs.com/codeloveme/p/2690695.html
Copyright © 2011-2022 走看看