首先将i这个任务的重要度的正值用前向星挂在l上,负值挂在r+1上(差分)
对每个任务的重要度离散之后建一棵线段树,然后以时间为轴建一棵主席树
细节贼多(因为某个<=打成==调了2小时)
感谢zzy大佬,gyz大佬的帮忙查错orz
/**************************************************************
Problem: 3932
User: syh0313
Language: C++
Result: Accepted
Time:7308 ms
Memory:136720 kb
****************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#define lch a[n].lc
#define rch a[n].rc
using
namespace
std;
const
int
maxn=1e5+10;
int
n,m,ll[maxn],rr[maxn],cnt,lim,root[maxn],topt,lala;
long
long
b[maxn],pp[maxn],pre=1;
int
w[maxn<<2],to[maxn<<2],nt[maxn<<2],st[maxn<<2],tot;
struct
da{
int
lc,rc;
long
long
sum,si;}a[maxn*50];
map<
int
,
int
>f,line,ff;
void
add(
int
x,
int
y,
int
z)
{to[++tot]=y; nt[tot]=st[x]; st[x]=tot; w[tot]=z;}
void
updata(
int
n)
{
a[n].si=a[lch].si+a[rch].si;
a[n].sum=a[lch].sum+a[rch].sum;
}
void
build_tree(
int
&n,
int
l,
int
r)
{
n=++topt;
if
(l==r)
return
;
int
mid=(l+r)>>1;
build_tree(lch,l,mid); build_tree(rch,mid+1,r);
}
void
tree_add(
int
old,
int
&n,
int
l,
int
r,
int
lc,
long
long
k)
{
if
(n
if
(l==r && r==lc)
{
if
(ff[lc]<=lala)
{
ff[lc]=lala+1;
a[n].si=a[old].si+k;
a[n].sum=a[old].sum+1ll*k*b[lc];
}
else
{a[n].si+=k; a[n].sum+=1ll*k*b[lc];}
return
;
}
int
mid=(l+r)>>1;
if
(lc<=mid) {
if
(!rch) rch=a[old].rc; tree_add(a[old].lc,lch,l,mid,lc,k);}
else
{
if
(!lch) lch=a[old].lc; tree_add(a[old].rc,rch,mid+1,r,lc,k);}
updata(n);
}
long
long
qury(
int
n,
int
l,
int
r,
int
k)
{
if
(l==r)
return
1ll*k*b[l];
if
(!k)
return
0;
int
mid=(l+r)>>1;
if
(a[lch].si>=k)
return
qury(lch,l,mid,k);
else
return
a[lch].sum+qury(rch,mid+1,r,k-a[lch].si);
}
int
main()
{
//freopen("1.in","r",stdin);
//freopen("my.out","w",stdout);
scanf
(
"%d%d"
,&n,&m);
for
(
int
i=1;i<=n;i++)
{
scanf
(
"%d%d%lld"
,&ll[i],&rr[i],&pp[i]);
if
(!f[pp[i]]) {f[pp[i]]=1; b[++cnt]=pp[i];}
}
sort(b+1,b+cnt+1);
for
(
int
i=1;i<=cnt;i++) line[b[i]]=i;
for
(
int
i=1;i<=n;i++) add(ll[i],line[pp[i]],1),add(rr[i]+1,line[pp[i]],-1);
build_tree(root[0],1,cnt);
for
(
int
i=1;i<=m;i++)
{
int
p=st[i];
if
(!p)
{
root[i]=++topt;
a[root[i]].lc=a[root[i-1]].lc;
a[root[i]].rc=a[root[i-1]].rc;
a[root[i]].si=a[root[i-1]].si;
a[root[i]].sum=a[root[i-1]].sum;
}
lim=topt+1;
while
(p)
{
tree_add(root[i-1],root[i],1,cnt,to[p],w[p]);
p=nt[p];
}
lala++;
}
for
(
int
i=1;i<=m;i++)
{
int
xx;
long
long
aa,bb,cc,kk;
scanf
(
"%d%lld%lld%lld"
,&xx,&aa,&bb,&cc);
kk=1+(aa*pre+bb)%cc;
if
(kk>=a[root[xx]].si) pre=a[root[xx]].sum;
else
pre=qury(root[xx],1,cnt,kk);
printf
(
"%lld\n"
,pre);
}
return
0;
}