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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Love_mona/article/details/79802990

蒟蒻的垂死挣扎

这题改得我心力憔悴,自己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[N],b[N],yyb[N],tot,root[N];
struct mona { int le,ri; ll w; int sum; } tr[N];

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[N];
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));
    }
}

猜你喜欢

转载自blog.csdn.net/Love_mona/article/details/79802990