题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6464
题目大意:

已知一开始有一个空序列,接下来有Q次操作,每次操作给出type、first和second三个值。
当type为1时,意味着该操作属于第一种操作:往序列尾部添加first个second数。
当type为2时,意味着该操作属于第二种操作:查询序列中第first小至第second小的数值之和
(一共有(second- first + 1)个数被累加),并将结果对1000000007取模后输出。

单组数据 第一行一个Q(1 <= Q <= 1e5),代表Q次操作。
接下来有Q行,每行包含三个整数type、first和second;其中1 <= type <= 2。当type等于1时,0 <=
first,second < 1e9。当type等于2时,1 <= first <=
second,且first和second均不大于目前已添加进序列的数的数量。

对于每次操作二,将结果对1000000007取模后输出。

Sample Input
6
1 5 1
1 6 3
2 2 5
2 4 8
1 2 2
2 4 8

Sample Output
4
11
9

思路:q<=1e5。那么我们把数据离散化后。保存在一棵权值线段树里。保存区间元素个数。区间和。

每次查询第[L, R]的和。二分第R前缀和-第L-1大前缀和。

#include<bits/stdc++.h>
#define LL long long
#define mid (l+r)/2
using namespace std;
const LL mod = 1000000007;

struct Q{
    LL a, b, c;
}q[100005];

LL A[100005], B[100005], tot=0;

struct Node{
    LL l, r;
    LL cut, sum, pos;
}node[1000000];

void BT(LL i, LL l, LL r){
    node[i].l=l;
    node[i].r=r;
    if(l==r){
        node[i].cut=node[i].sum=node[i].pos=0;
        return ;
    }
    BT(i<<1, l, mid);
    BT((i<<1)+1, mid+1, r);
}

void GX(LL i, LL x, LL y, LL z){

    if(node[i].l==node[i].r){
        //cout<<i<<" "<<node[i].l<<" "<<node[i].r<<" "<<x<<" "<<y<<" "<<z<<endl;
        node[i].pos=z;
        node[i].cut+=y;
        node[i].sum=(node[i].cut*z)%mod;
        return ;
    }
    if(x<=(node[i].l+node[i].r)/2){
        GX(i<<1, x, y, z);
    }
    else{
        GX((i<<1)+1, x, y, z);
    }
    node[i].cut=node[i<<1].cut+node[(i<<1)+1].cut;
    node[i].sum=(node[i<<1].sum+node[(i<<1)+1].sum)%mod;

}

LL ans=0;
void CX(LL i, LL k){
    
    if(k==0){//特判
        return ;
    }
    if(node[i].l==node[i].r){

        ans+=(node[i].pos*k)%mod;
        ans%=mod;
        return ;
    }
    if(node[i<<1].cut>=k){
        CX(i<<1, k);
    }
    else{
        ans+=node[i<<1].sum;
        ans%=mod;
        CX((i<<1)+1, k-node[i<<1].cut);
    }

}

int main(){

    LL n, a, b, c;
    scanf("%lld", &n);
    for(LL i=1; i<=n; i++){
        scanf("%lld%lld%lld", &q[i].a, &q[i].b, &q[i].c);
        if(q[i].a==1){
            A[++tot]=q[i].c;
        }
    }
    BT(1, 1, 100000);
    sort(A+1, A+1+tot);
    LL cut=unique(A+1, A+tot+1)-A-1;
    for(LL i=1; i<=n; i++){
        if(q[i].a==1){
            LL x=lower_bound(A+1, A+1+cut, q[i].c) - A ;
            GX(1, x, q[i].b, q[i].c);
        }
        else{
            LL L=q[i].b, R=q[i].c;
            ans=0;
            CX(1, L-1);
            LL s=-ans;
            ans=0;
            CX(1, R);
            s+=ans;
            printf("%lld\n", (s+mod)%mod);
        }
    }

    return 0;
}