洛谷P3168 [CQOI2015]任务查询系统

最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分。超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同。调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。

                                          --by 洛谷;

https://daniu.luogu.org/problem/show?pid=3168



主席树(可持久化线段树)

考虑离散优先级(即权值);

以时间为序列,维护主席树(主席树的详解见这个

然后把询问处理为在S处加入,在E+1处删除之

跑就好了;

注意内存池开到4e6以上(我会说我因为这个卡了一个月??)

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct ss{
 5     long long tim,val,p;
 6 }x[200001];
 7 long long a[200001];
 8 struct pool{
 9     int l,r;
10     long long sum,size;
11 }data[4000050];
12 int n,m,tot;
13 int fa[100001]; 
14 long long A,B,C,pre;
15 
16 bool cmpt(ss x,ss y){
17     return x.tim<y.tim;
18 }
19 bool cmpv(ss x,ss y){
20     return x.val<y.val;
21 }
22 
23 void add(int ,int ,int ,int );
24 long long find(int ,int ,int ,long long  );
25 
26 int main()
27 {
28     int i,j,k,l,o;
29     scanf("%d%d",&m,&n);
30     for(i=1;i<=m;i++){
31         scanf("%d%d%d",&j,&k,&l);
32         x[(i<<1)-1].tim=j;x[(i<<1)-1].val=l;
33         x[i<<1].tim=k+1;x[i<<1].val=l;
34         x[i<<1].p=-1;x[(i<<1)-1].p=1;
35     }
36     sort(x+1,x+2*m+1,cmpv);
37     j=0;
38     for(i=1;i<=2*m;i++){
39         if(x[i].val!=a[j]){
40             a[++j]=x[i].val;
41             x[i].val=j;
42         }
43         x[i].val=j;
44     }
45     k=j;
46     sort(x+1,x+2*m+1,cmpt);
47     j=1;
48     for(i=1;i<=n;i++){
49         fa[i]=++tot;
50         data[fa[i]]=data[fa[i-1]];
51         while(x[j].tim==i)
52             add(fa[i],j,1,k),j++;
53     }
54     pre=1;
55     for(i=1;i<=n;i++){
56         scanf("%d%lld%lld%lld",&j,&A,&B,&C);
57         pre=find(fa[j],1,k,(A*pre+B)%C+1);
58         printf("%lld
",pre);
59     }
60     return 0;
61 }
62 
63 void add(int now,int ma,int l,int r)
64 {
65     data[now].size+=x[ma].p;
66     data[now].sum+=a[x[ma].val]*x[ma].p;
67     if(l>=r)    return;
68     int mid=(l+r)>>1;
69     if(x[ma].val<=mid){
70         data[++tot]=data[data[now].l];
71         data[now].l=tot;
72         add(data[now].l,ma,l,mid);
73     }
74     else{
75         data[++tot]=data[data[now].r];
76         data[now].r=tot;
77         add(data[now].r,ma,mid+1,r);
78     }
79 }
80 
81 long long find(int now,int l,int r,long long ma)
82 {
83     long long sum;
84     if(ma==0)return 0;
85     if(ma>=data[now].size||l==r){
86         sum=data[now].sum;
87         if(l==r&&data[now].size>ma)sum=(sum*ma)/data[now].size;
88         return sum;
89     }
90     int mid=(l+r)>>1;
91     if(ma<=data[data[now].l].size)
92         return find(data[now].l,l,mid,ma);
93     else
94         return data[data[now].l].sum+find(data[now].r,mid+1,r,ma-data[data[now].l].size);
95 }

祝AC哟!

原文地址:https://www.cnblogs.com/nietzsche-oier/p/6425901.html