题目链接: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;
}