您的位置:首页 > 其它

主席树练习5——P3168 [CQOI2015]任务查询系统

2018-04-03 14:35 573 查看

蒟蒻的垂死挣扎

这题改得我心力憔悴,自己yy一下发现就是个差分,在l 处 +1,r+1 处 -1即可,然后按照时间排序,一项项处理即可,然后我就螺旋升天爆炸了。
记得不用修改的时间点也开一棵  ORZ。
// luogu-judger-enable-o2
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#define RG register
#define N 5000100
#define ll long long
#define ld long double
using namespace std;

inline ll read(){
RG ll x=0,o=1; RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*o;
}

int len,n,m,a
,b
,yyb
,tot,root
;
struct mona { int le,ri; ll w; int sum; } tr
;

inline void Build(RG int l,RG int r,RG int &x,RG ll w,RG ll op){
tr[++tot]=tr[x],tr[tot].sum+=op,tr[tot].w+=op*yyb[w],x=tot;
if(l==r) return ;
RG int mid=(l+r)>>1;
if(w<=mid) Build(l,mid,tr[x].le,w,op);
else Build(mid+1,r,tr[x].ri,w,op);
}

inline ll Query(RG int l,RG int r,RG int x,RG int k){
if(l==r) return 1LL*yyb[l]*k;
RG int mid=(l+r)>>1;
RG int num=tr[tr[x].le].sum;
if(k<=num) return Query(l,mid,tr[x].le,k);
else return Query(mid+1,r,tr[x].ri,k-num)+tr[tr[x].le].w;
}

struct joker{ int t,op; ll w; } p
;
bool cmp(joker x,joker y) { return x.t<y.t; }
inline void Orz(){
sort(yyb+1,yyb+1+n);
len=unique(yyb+1,yyb+1+n)-yyb-1;
for(RG int i=1;i<=(n<<1);++i)
p[i].w=lower_bound(yyb+1,yyb+1+len,p[i].w)-yyb;
}
int main(){
n=read(),m=read();
for(RG int i=1;i<=n;++i){
RG int x=read(),y=read(),w=yyb[i]=read();
p[(i<<1)-1]=(joker) { x , 1,w };
p[(i<<1)] =(joker) { y+1,-1,w };
} sort(p+1,p+1+(n<<1),cmp),Orz();
for(RG int t=1,i=1;t<=n;++t){
root[t]=root[t-1];
for(;t==p[i].t;++i)
Build(1,len,root[p[i].t],p[i].w,p[i].op);
}RG ll pre=1;
for(RG int i=1;i<=m;++i){
RG ll x=read(),aa=read(),bb=read(),cc=read();
RG ll kk=1+(aa*pre+bb)%cc; kk=min(kk,(ll) tr[root[x]].sum);
printf("%lld\n",pre=Query(1,len,root[x],kk));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  主席树