在区间
[
S
i
,
E
i
]
[S_i,E_i]
[Si,Ei]内添加一个优先级为
P
i
P_i
Pi的任务 —— 区间修改
查询时刻
x
x
x时前
k
k
k个优先级之和 ——单点查询
区间修改,单点查询,因此想到差分。查询前
k
k
k个数之和,想到主席树。
差分时,把
[
S
i
,
E
i
]
[S_i,E_i]
[Si,Ei]的区间转化为在
S
i
S_i
Si处
+
1
+1
+1,在
E
i
E_i
Ei处
−
1
-1
−1。
主席树中维护两个值:
n
u
m
[
r
t
]
num[rt]
num[rt]表示以
r
t
rt
rt为根的主席树中有多少个数在区间内。
s
u
m
[
r
t
]
sum[rt]
sum[rt]表示以
r
t
rt
rt为根的主席树的所有值的和。
然后
u
p
d
a
t
e
update
update时分别维护,查询就是普通的求和操作。
毒瘤代码
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#define re register int
#define rl register ll
using namespace std;
typedef long long ll;
ll read() {
rl x=0,f=1;
char ch=getchar();
while(ch<'0' || ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') {
x=10*x+ch-'0';
ch=getchar();
}
return x*f;
}
namespace I_Love {
const int Size=200005;
const int LOG=20;
struct Task {
int x; ll p;
} w[Size];
int n,m,maxn,tot,T[Size];
int ls[Size*LOG],rs[Size*LOG],num[Size*LOG];
ll a[Size],sum[Size*LOG];
int update(int pre,int l,int r,int x,int v,ll pri) {
int rt=++tot;
ls[rt]=ls[pre]; rs[rt]=rs[pre];
num[rt]=num[pre]+v;
sum[rt]=sum[pre]+pri;
if(l<r) {
int mid=(l+r)>>1;
if(x<=mid) {
ls[rt]=update(ls[pre],l,mid,x,v,pri);
} else {
rs[rt]=update(rs[pre],mid+1,r,x,v,pri);
}
}
return rt;
}
ll query(int l,int r,ll k,int rt) {
if(l==r) return a[l]*k;
int mid=(l+r)>>1,x=num[ls[rt]];
if(k<=x) return query(l,mid,k,ls[rt]);
return sum[ls[rt]]+query(mid+1,r,k-x,rs[rt]);
}
inline bool comp(Task jzm,Task xjp) {
return jzm.x<xjp.x;
}
void Fujibayashi_Ryou() {
m=read();
n=read();
for(re i=1; i<=m; i++) {
w[i].x=read();
w[i+m].x=read()+1;
a[i]=w[i].p=read();
w[i+m].p=-w[i].p;
}
sort(a+1,a+1+m);
maxn=unique(a+1,a+1+m)-(a+1);
int pos=1;
sort(w+1,w+1+(m<<1),comp);
for(int i=1; i<=(m<<1); i++) {
for(re j=w[i-1].x+1; j<=w[i].x; j++) T[j]=T[j-1];
int tmp=lower_bound(a+1,a+1+maxn,abs(w[i].p))-a;
if(w[i].p>0) {
T[w[i].x]=update(T[w[i].x],1,maxn,tmp,1,w[i].p);
} else {
T[w[i].x]=update(T[w[i].x],1,maxn,tmp,-1,w[i].p);
}
}
ll pre=1;
for(re i=1; i<=n; i++) {
ll x=read();
ll A=read();
ll B=read();
ll C=read();
ll k=(A*pre+B)%C+1ll;
if(num[T[x]]<=k) {
printf("%lld\n",pre=sum[T[x]]);
} else {
printf("%lld\n",pre=query(1,maxn,k,T[x]));
}
}
}
}
int main() {
I_Love::Fujibayashi_Ryou();
return 0;
}