假如 个蚊子的位置都不一样的话,维护区间最大值。因为每个位置只会被访问一遍,所以复杂度还是
。当遇到这个区间的最大值小于要拍死的体型最小值时,就退出,不然递归到叶子节点。现在因为
个蚊子的位置可能重叠,那么其实我们可以排个序拍扁序列,重新排列一下位置,记录下来即可。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int ml[maxn],mr[maxn],vs[maxn],n,m,ct;
struct nd{
int pos,w;
inline bool operator<(const nd&x)const{
return pos!=x.pos?pos<x.pos:w<x.w;
}
}a[maxn];
struct node{
int l,r;
ll w,mx;
}t[maxn<<2];
inline void pushup(int k)
{
t[k].mx=max(t[k<<1].mx,t[k<<1|1].mx);
t[k].w=t[k<<1].w+t[k<<1|1].w;
}
inline void build(int k,int l,int r)
{
t[k].l=l,t[k].r=r;
if(l==r){t[k].w=t[k].mx=a[l].w; return;}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k); return;
}
inline ll update(int k,int l,int r,int p)
{
int x=t[k].l,y=t[k].r;
if(l<=x&&y<=r&&t[k].mx<p)return 0;
if(x==y)
{
ll res=t[k].w;
t[k].w=t[k].mx=0;
return res;
}
int mid=x+y>>1; ll res=0;
if(l<=mid)res+=update(k<<1,l,r,p);
if(mid<r)res+=update(k<<1|1,l,r,p);
pushup(k); return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>ct>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i].pos>>a[i].w;
sort(a+1,a+1+n); memset(ml,127/5,sizeof(ml));
for(int i=1;i<=n;i++)
{
vs[a[i].pos]=3;
ml[a[i].pos]=min(ml[a[i].pos],i);
mr[a[i].pos]=max(mr[a[i].pos],i);
}
for(int i=1;i<=n;i++)
{
if(vs[i]>2)
{
for(int j=i-1;j>=1;j--)
{
if(vs[j]>2)break; ml[j]=ml[i];
}
for(int j=i+1;j<=n;j++)
{
if(vs[j]>2)break; mr[j]=mr[i];
}
}
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int l,r,p; cin>>l>>r>>p;
if(ml[l]<=mr[r])cout<<update(1,ml[l],mr[r],p)<<"\n";
else cout<<0<<"\n";
}
return 0;
} 
京公网安备 11010502036488号