[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]相关的知识,希望对你有一定的参考价值。

Description

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

Input

输入文件第一行包含两个空格分开的正整数m和n,分别表示任务总数和时间范围。接下来m行,每行包含三个空格
分开的正整数Si、Ei和Pi(Si≤Ei),描述一个任务。接下来n行,每行包含四个空格分开的整数Xi、Ai、Bi和Ci,
描述一次查询。查询的参数Ki需要由公式 Ki=1+(Ai*Pre+Bi) mod Ci计算得到。其中Pre表示上一次查询的结果,
对于第一次查询,Pre=1。
 
 

Output

输出共n行,每行一个整数,表示查询结果。
 

Sample Input

4 3
1 2 6
2 3 3
1 3 2
3 3 4
3 1 3 2
1 1 3 4
2 2 4 3

Sample Output

2
8
11

HINT

样例解释

K1 = (1*1+3)%2+1 = 1

K2 = (1*2+3)%4+1 = 2

K3 = (2*8+4)%3+1 = 3

对于100%的数据,1≤m,n,Si,Ei,Ci≤100000,0≤Ai,Bi≤100000,1≤Pi≤10000000,Xi为1到n的一个排列

 


正在学主席树。。听说这个题是个模板题就跑去做了。。
如果你不知道什么是主席树的话建议出门左转去学。。
对于每一个时间点我们建一个版本的权值线段树,每个线段树记录当前结点的任务数与这个结点的任务优先级之和。
一个任务从i到j的话就给第i个版本++,第j+1个版本--;
但是我们需要考虑几个事情
1.pi太大,需要离散化,这是很显然的。
2.修改了第x个版本的话后面所有版本都需要更改。
对于1我的方法是把所有优先级先序排序去重然后依次放到数组里,因为排了序了所以它们的大小关系不会改变,然后通过二分找到离散化以后的值(但是被dalao嘲讽了)
对于2我的方法是把所有操作按时间点大小先序排序,然后依次进行操作,如果当前的操作点比目前建的树要大那就开到那个时间点
这个意思
1 for(int i=1;i<=操作数;++i)
2 {
3     while(已经建了p个<a[i].time){建树(++p);}
4     操作:加或减
5 }

因为我之后建的树会复制前面的树的值,而前面的树的操作都是已经做完了的,然后这个操作是2*m+n。

当然这个也被dalao嘲讽了。。

然后有一个东西要考虑(我就是错了这个)

就是你查询到叶子结点的时候,它的任务数可能会比你剩下要查的个数要大,这样你就不需要取走全部了。。似乎是一个很显然的事情但我当时做却没想到。

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #define N (100000+5)
  7 #define ll long long
  8 using namespace std;
  9 inline ll read()
 10 {
 11     char ch=getchar();ll kin=1,gi=0;
 12     while(ch>9||ch<0){if(ch==-)kin=-1;ch=getchar();}
 13     while(ch>=0&&ch<=9){gi=gi*10+ch-48;ch=getchar();}
 14     return kin*gi;
 15 }
 16 struct tree
 17 {
 18     ll num;
 19     ll simple;
 20     ll son[2];
 21     ll l,r,fl;
 22 }d[5000005];
 23 struct naive
 24 {
 25     ll nic;
 26     ll st;
 27     bool fl;
 28 }ni[N*2];
 29 bool cmp(naive x,naive y)
 30 {
 31     return x.st<y.st;
 32 }
 33 ll n,m,siz,rt[N];
 34 ll sot[N],trl[N],kiz,fis,trik;
 35 ll pre=1,lis[N],ra,rig;
 36 void make(ll,ll,bool);
 37 ll query(ll,ll);
 38 void build(ll,ll,ll);
 39 void rut(ll);
 40 ll mmid(ll x)
 41 {
 42     ll l=1,r=kiz,res=0;
 43     while(l<=r)
 44     {
 45         ll mid=(l+r)>>1;
 46         if(trl[mid]<=x){l=mid+1;res=mid;}
 47         else r=mid-1;
 48     }
 49     return res;
 50 }
 51 int main()
 52 {
 53     m=read();n=read();
 54     for(ll i=1;i<=m;++i)
 55     {
 56 
 57         ni[++trik].st=read();ni[trik].fl=1;
 58         ni[++trik].st=read()+1;ni[trik].fl=0;
 59         ni[trik-1].nic=ni[trik].nic=read();
 60         sot[i]=ni[trik].nic;
 61     }
 62     sort(sot+1,sot+m+1);
 63     sort(ni+1,ni+trik+1,cmp);
 64     for(ll i=1;i<=m;++i)if(sot[i]!=sot[i-1])trl[++kiz]=sot[i];
 65     for(ll i=1;i<=trik;++i)
 66     {
 67         if(ni[i].st>n)break;
 68         while(fis<ni[i].st){rut(++fis);}
 69         ll rik=mmid(ni[i].nic);
 70         make(ni[i].st,rik,ni[i].fl);
 71     }
 72     while(fis<n){rut(++fis);}
 73     for(ll i=1;i<=n;++i)
 74     {
 75         ll sec=read();
 76         ll a,b,c,k;
 77         a=read();b=read();c=read();
 78         k=(a*pre+b)%c+1;
 79         printf("%lld\\n",pre=query(sec,k));
 80     }
 81     return 0;
 82 }
 83 ll query(ll x,ll y)
 84 {
 85     ll nw=rt[x],res=0;
 86     y=min(y,d[nw].simple);
 87     while(1)
 88     {
 89         if(y==0)break;
 90         if(d[nw].l==d[nw].r&&d[nw].simple>y){res+=trl[d[nw].l]*y;break;}
 91         if(d[nw].simple<=y){res+=d[nw].num;break;}
 92         if(d[d[nw].son[0]].simple<=y) y-=d[d[nw].son[0]].simple,res+=d[d[nw].son[0]].num,nw=d[nw].son[1];
 93         else nw=d[nw].son[0];
 94     }
 95     return res;
 96 }
 97 void make(ll x,ll num,bool p)
 98 {
 99     ll nw=rt[x];bool f;
100     while(d[nw].l!=d[nw].r)
101     {
102         if(p)
103         {d[nw].num+=trl[num];d[nw].simple++;}
104         else
105         {d[nw].num-=trl[num];d[nw].simple--;}
106         f=(num>(d[nw].l+d[nw].r)>>1);
107         if(d[d[nw].son[f]].fl!=x)
108         {
109             d[++siz]=d[d[nw].son[f]];
110             d[nw].son[f]=siz;
111             d[siz].fl=x;
112         }
113         nw=d[nw].son[f];
114     }
115         if(p)
116         {d[nw].num+=trl[num];d[nw].simple++;}
117         else
118         {d[nw].num-=trl[num];d[nw].simple--;}
119 }
120 void rut(ll p)
121 {
122     ll x;
123     x=rt[p]=++siz;
124     d[x].l=1;d[x].r=kiz;d[x].fl=1;
125     if(x>1)
126     {
127         d[rt[p]]=d[rt[p-1]];
128         d[rt[p]].son[0]=d[rt[p-1]].son[0];
129         d[rt[p]].son[1]=d[rt[p-1]].son[1];
130     }
131     else
132     {
133         d[x].son[0]=++siz;
134         build(d[x].son[0],1,(kiz+1)>>1);
135         d[x].son[1]=++siz;
136         build(d[x].son[1],((kiz+1)>>1)+1,kiz);
137     }
138 }
139 void build(ll x,ll l,ll r)
140 {
141     d[x].l=l;d[x].r=r;d[x].fl=1;
142     if(l!=r)
143     {
144         d[x].son[0]=++siz;
145         build(siz,l,(l+r)>>1);
146         d[x].son[1]=++siz;
147         build(siz,((l+r)>>1)+1,r);
148     }
149 }
bzoj3932

 

以上是关于[bzoj3932][CQOI2015]任务查询系统-题解[主席树][权值线段树]的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3932:[CQOI2015]任务查询系统——题解

[bzoj3932][CQOI2015]任务查询系统

bzoj 3932: [CQOI2015]任务查询系统

bzoj3932 [CQOI2015]任务查询系统——主席树

bzoj 3932 [CQOI2015]任务查询系统 (主席树)

[bzoj3932][CQOI2015][任务查询系统] (主席树)