hdu6464 线段树
Posted virtu0s0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans);
}
}
}
以上是关于hdu6464 线段树的主要内容,如果未能解决你的问题,请参考以下文章