• HDU 6464 /// 权值线段树


    题目大意:

    共Q次操作 操作有两种

    操作一 在序列尾部加入f[i]个s[i]

    操作二 查询序列第f[i]小到第s[i]小之间的总和

    离线操作 把序列内的值离散化

    然后利用离散化后的值 在线段树上对应权值操作

    权值线段树维护权值对应的值的个数和总和

    查询 用s[i]的前缀和减去f[i]-1的前缀和 具体看注释

    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define INF 0x3f3f3f3f
    #define mem(i,j) memset(i,j,sizeof(i))
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    #define gcd(i,j) __gcd(i,j);
    const int N=1e5+5;
    const int mod=1000000007;
    
    LL p[N], f[N], s[N];
    LL cop[N], tot;
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    LL num[N<<2], sum[N<<2];
    void pushUp(int rt) {
        num[rt]=num[rt<<1]+num[rt<<1|1];
        sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%mod;
    }
    void update(LL ind,LL k,int l,int r,int rt) {
        if(l==r) {
            num[rt]+=k; // 这个值在序列内的个数
            sum[rt]=(sum[rt]+cop[ind]*k)%mod; // 总和
            return ;
        }
        int m=(l+r)>>1;
        if(m>=ind) update(ind,k,lson);
        else update(ind,k,rson);
        pushUp(rt);
    }
    LL query(LL k,int l,int r,int rt) {
        if(k==0) return 0;
        if(l==r) return k*cop[l]%mod; 
        // 在l位置 还差k个 k可能不需要num[l]那么多 
        // 所以应该是k*cop[l] 而不是sum[l]
        int m=(l+r)>>1, L=rt<<1;
        if(num[L]<=k) return (sum[L]+query(k-num[L],rson))%mod;
        // 左儿子区间不足k个 那么左儿子区间的总和+右儿子区间差的个数的总和
        else return query(k,lson);
        // 左儿子区间的数已超过k个 就在左儿子区间内继续缩小
    }
    
    int main()
    {
        mem(num,0LL); mem(sum,0LL);
        int q; scanf("%d",&q);
        inc(i,1,q) scanf("%lld%lld%lld",&p[i],&f[i],&s[i]);
        tot=0;
        inc(i,1,q) if(p[i]==1)
            cop[++tot]=s[i];
        sort(cop+1,cop+1+tot);
        tot=unique(cop+1,cop+1+tot)-cop-1;
        inc(i,1,q) {
            if(p[i]==1) {
                int ind=lower_bound(cop+1,cop+1+tot,s[i])-cop;
                update(ind,f[i],1,tot,1); // 离散化后的值在对应权值位置操作
            }
            else {
                LL R=query(s[i],1,tot,1);
                LL L=query(f[i]-1,1,tot,1);
                printf("%lld
    ",(R-L+mod)%mod); 
            }
        }
    
        return 0;
    }
    
     
    View Code
  • 相关阅读:
    curl命令学习笔记
    IOS安全测试思维导图
    Hello World
    Hive SQL使用和数据加载的一点总结
    采用最低松弛度优先调度的实时系统调度程序
    MongoDB Map Reduce速度提升20倍的优化宝典
    释放时间不同可中断平行机问题在线算法
    RPC框架系列——Avro
    Solr 3.6.2索引MySQL数据库配置过程
    IKAnalyzer 独立使用 配置扩展词库
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10560355.html
Copyright © 2020-2023  润新知