• hdu6464 线段树


    http://acm.hdu.edu.cn/showproblem.php?pid=6464

    题意

    一个空序列,q次操作,一种是往序列后插入x个y,另一种是查询序列中第x小到第y小的数字之和

    题解

    • 线段树维护区间和,区间个数

    代码

    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    const int MAXN=1e5+5;
    const int P=1e9+7;
    ll V[MAXN<<2],W[MAXN<<2],b[MAXN],lt[MAXN],x[MAXN],y[MAXN];
    int sz=0,Q[MAXN];
    int tot=0;
    
    void push_up(int o){
        V[o]=V[o<<1]+V[o<<1|1];V[o]%=P;
        W[o]=W[o<<1]+W[o<<1|1];
    }
    void ud(int o,int l,int r,int p,ll v){
        if(l==r){W[o]+=v;V[o]+=b[l]%P*v%P;V[o]%=P;return;}
        int mid=(l+r)/2;
        if(p<=mid)ud(o<<1,l,mid,p,v);
        else ud(o<<1|1,mid+1,r,p,v);
        push_up(o);
    }
    int search(int o,int l,int r,ll k){
        if(l==r){lt[++tot]=k;return l;}
        int mid=(l+r)/2;
        if(k<=W[o<<1])return search(o<<1,l,mid,k);
        else return search(o<<1|1,mid+1,r,k-W[o<<1]);
    }
    ll qy(int o,int l,int r,int L,int R){
        if(L>R)return 0;
        if(L<=l&&r<=R)return V[o];
        int mid=(l+r)/2;
        ll ans=0;
        if(L<=mid){ans+=qy(o<<1,l,mid,L,R);ans%=P;}
        if(R>mid){ans+=qy(o<<1|1,mid+1,r,L,R);ans%=P;}
        return ans;
    }
    ll qW(int o,int l,int r,int p){
        if(l==r)return W[o];
        int mid=(l+r)/2;
        if(p<=mid)return qW(o<<1,l,mid,p);
        else return qW(o<<1|1,mid+1,r,p);
    }
    
    int q;
    int id(ll x){
        return lower_bound(b+1,b+sz+1,x)-b;
    }
    int main(){
        cin>>q;
        for(int i=0;i<q;i++){
            scanf("%d%lld%lld",&Q[i],&x[i],&y[i]);
            if(Q[i]==1)b[++sz]=y[i];
        }
        sort(b+1,b+sz+1);sz=unique(b+1,b+sz+1)-(b+1);
        //for(int i=1;i<=sz;i++)cout<<b[i]<<" ";
        //cout<<endl;
        for(int i=0;i<q;i++){
            if(Q[i]==1){
                ud(1,1,sz,id(y[i]),x[i]);
            }else{
                tot=0;
                int A=search(1,1,sz,x[i]);
                int B=search(1,1,sz,y[i]);    
                //cout<<A<<" "<<B<<endl;
                ll ans=0;
                if(A==B){ans=(lt[2]-lt[1]+1)*b[A]%P;}
                else{
                    ans=qy(1,1,sz,A+1,B-1);
                    ans+=(qW(1,1,sz,A)-lt[1]+1)*b[A]%P;ans%=P;
                    ans+=lt[2]*b[B]%P;ans%=P;
                }
                printf("%lld
    ",ans);
            }
        }
    }
    
  • 相关阅读:
    ntp时间服务器
    locate 命令
    身份验证器
    centos 6 mysql源码安装
    简单上传下载命令lrzsz
    iptables记录日志
    iptables日志探秘
    du 命令
    Codeforces 1097F Alex and a TV Show (莫比乌斯反演)
    线段树教做人系列(1)HDU4967 Handling the Past
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10817219.html
Copyright © 2020-2023  润新知