rt,没看出来啥问题,有没有佬帮忙看看/kk
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define U unsigned
#define int long long
#define P pair<int,int>
#define pb push_back
#define MP make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
#define debug(x) cerr<<#x<<'='<<x<<endl
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
#define pcn putchar('\n')
#define pcs putchar(' ');
#define pc putchar
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
#define ClockB clock_t start,end; start = clock();
#define ClockE end = clock(); cerr<<"time = "<<double(end-start)/CLOCKS_PER_SEC<<"s"<<endl;
#define lc (idx<<1)
#define rc (idx<<1|1)
using namespace std;
namespace FrictionalF{
int _=1;
inline int rd(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
inline void wr(int x){
if(x<0) pc('-'),x=(~x)+1;
if(x>9) wr(x/10);
pc((x%10)^48);
}
int n,m;
const int N=1e5+5;
int a[N],b[N];
int op[N],x[N],y[N];
vector<int>li;
map<int,int>mach;
int sum[N*2];
struct node{
int l,r,sum,tag;
}tree[N*8];
void pushup(int idx){
tree[idx].sum=tree[lc].sum+tree[rc].sum;
}
int top;
void build(int idx,int l,int r){
tree[idx].l=l,tree[idx].r=r;
if(l==r){
mach[l]=idx;
return ;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
}
void AddLazy(int idx,int val){
tree[idx].tag+=val;
tree[idx].sum+=val*(tree[idx].r-tree[idx].l+1);
}
void pushdown(int idx){
AddLazy(lc,tree[idx].tag);
AddLazy(rc,tree[idx].tag);
tree[idx].tag=0;
}
void update(int idx,int l,int r,int val){
if(l<=tree[idx].l&&r>=tree[idx].r){
AddLazy(idx,val);
return ;
}
int mid=(tree[idx].l+tree[idx].r)>>1;
pushdown(idx);
if(l<=mid) update(lc,l,r,val);
if(r>mid) update(rc,l,r,val);
pushup(idx);
}
void change(int x,int y){
int tmp=mach[x];
update(1,tmp,top-1,y);
}
int query(int idx,int l,int r){
if(l<=tree[idx].l&&r>=tree[idx].r) return tree[idx].sum;
int mid=(tree[idx].l+tree[idx].r)>>1;
int ans=0;
pushdown(idx);
if(l<=mid) ans+=query(lc,l,r);
if(r>mid) ans+=query(rc,l,r);
return ans;
}
int calcl(int x){
int l=-1,r=top,mid;
while(l<r-1){
mid=(l+r)>>1;
if(li[mid]<x) l=mid;
else r=mid;
}
return r;
}
int calcr(int x){
int l=-1,r=top,mid;
while(l<r-1){
mid=(l+r)>>1;
if(li[mid]<=x) l=mid;
else r=mid;
}
return l;
}
signed main(){
// _=rd();
while(_--){
n=rd(),m=rd();
FOR(i,1,n) a[i]=rd(),b[i]=rd(),li.pb(a[i]);
FOR(i,1,m){
op[i]=rd(),x[i]=rd(),y[i]=rd();
if(op[i]==2) li.pb(x[i]);
}
sort(all(li));
top=unique(li.begin(),li.end())-li.begin();
FOR(i,0,top-1) mach[li[i]]=i;
build(1,0,top-1);
FOR(i,1,n) change(a[i],b[i]);
FOR(i,1,m){
if(op[i]==1){
int l,r;
l=calcl(x[i]),r=calcr(y[i]);
// debug(l),debug(r);
if(r<0) cout<<"0.0000\n";
else printf("%.4lf\n",query(1,l,r)*1.0/(y[i]-x[i]+1));
}
else change(x[i],y[i]);
}
}
return 0;
}
}
signed main(){
return FrictionalF::main();
}
思路就是把询问和初始的书离线下来建树,离散化一下,求前缀和的区间和。
如果您不想调我的代码,给一个 hack 也是可以的。