[CQOI2015]任务查询系统

题目链接:

    P3168 [CQOI2015]任务查询系统

 

solution:

  主席树难题.区间修改单点查询,这本是普通线段树可以做到的.但本题思维难度较大,要求我们求区间前$k$小,为了空间防爆,故将代价离散,然后以时间排序,主席树维护前缀和即可.

code:

  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #define R register
 9 #define next awawn
10 #define debug puts("mlg")
11 #define maxn 200010
12 using namespace std;
13 typedef long long ll;
14 typedef long double ld;
15 typedef unsigned long long ull;
16 inline ll read();
17 inline void write(ll x);
18 inline void writesp(ll x);
19 inline void writeln(ll x);
20 ll m,n;
21 struct node{
22     ll x,z;
23     bool operator < (const node &X)const{return x<X.x;}
24 }a[maxn<<1];
25 struct Node{
26     ll ls,rs,cnt,sum;
27 }t[maxn<<5]; 
28 ll tot,q,K,b[maxn];
29 ll rt[maxn<<5],Cnt;
30 ll p,pre=1;
31 
32 inline void build(ll &Rt,ll l,ll r){
33     Rt=++Cnt;
34     if(l==r) return;
35     ll mid=l+r>>1;
36     build(t[Rt].ls,l,mid);build(t[Rt].rs,mid+1,r);
37 }
38 
39 inline ll update(ll fa,ll l,ll r,ll k){
40     ll Rt=++Cnt;
41     t[Rt]=t[fa];
42     if(l==r){
43         t[Rt].cnt+=k;
44         t[Rt].sum+=k*b[p];
45         return Rt;
46     }
47     ll mid=l+r>>1;
48     if(p<=mid) t[Rt].ls=update(t[Rt].ls,l,mid,k);
49     else t[Rt].rs=update(t[Rt].rs,mid+1,r,k);
50     t[Rt].cnt=t[t[Rt].ls].cnt+t[t[Rt].rs].cnt;
51     t[Rt].sum=t[t[Rt].ls].sum+t[t[Rt].rs].sum;
52     return Rt;
53 }
54 
55 inline ll query(ll Rt,ll l,ll r,ll k){
56     if(l==r){return t[Rt].sum/t[Rt].cnt*k;}    
57     ll mid=l+r>>1;
58     if(k<=t[t[Rt].ls].cnt) return query(t[Rt].ls,l,mid,k);
59     else return t[t[Rt].ls].sum+query(t[Rt].rs,mid+1,r,k-t[t[Rt].ls].cnt);
60 }
61 
62 int main(){
63     n=read();m=read();
64     for(R ll i=1;i<=n;i++){
65         a[++tot].x=read();a[++tot].x=read()+1;
66         a[tot-1].z=b[i]=read();a[tot].z=-b[i];
67     }
68     sort(a+1,a+tot+1);sort(b+1,b+n+1);
69     q=unique(b+1,b+n+1)-b-1;
70     for(R ll i=1;i<=tot;i++){
71         while(K<a[i].x) rt[K+1]=rt[K],++K;
72         if(K==n+1) break;
73         p=lower_bound(b+1,b+q+1,abs(a[i].z))-b;
74         rt[K]=update(rt[K],1,q,a[i].z>0?1:-1);
75     }
76     for(R ll i=1,x,a,b,c;i<=m;i++){
77         x=read();a=read();b=read();c=read();
78         ll k=(a*pre+b)%c+1;
79         if(k>=t[rt[x]].cnt){
80             writeln(pre=t[rt[x]].sum);
81         }
82         else{
83             writeln(pre=query(rt[x],1,q,k));
84         }        
85     }
86 }
87 inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
88 inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
89 inline void writesp(ll x){write(x);putchar(' ');}
90 inline void writeln(ll x){write(x);putchar('\n');}

 

posted @ 2020-07-26 21:43  月落乌啼算钱  阅读(104)  评论(0编辑  收藏  举报