博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj3932 [CQOI2015]任务查询系统
阅读量:5105 次
发布时间:2019-06-13

本文共 3106 字,大约阅读时间需要 10 分钟。

3932: [CQOI2015]任务查询系统

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 4113  Solved: 1334
[][][]

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棵可以用来维护时间为1~i的优先级在[x,y]的任务个数和优先级之和.对于每一个时间点都建主席树则会有点浪费,因为每次更改操作只会设计到2个时间点.考虑用操作来建主席树.第i棵可以维护第1~i次操作后优先级在[x,y]的任务个数和优先级之和.那么每一次操作只需要在初始时间和结束时间+1处更改就行了(类似于差分).对操作的时间排序,接着求出每个时间点最后被影响的操作序号.最后查询就好了.
          搞清楚主席树表示的意义很重要!碰到第k小/大这种字眼也要很快反应过来该用什么方法,还要知道利用主席树要维护什么东西!与权值线段树联系起来思考.
#include 
#include
#include
#include
using namespace std;const int maxn = 200010;typedef long long ll;ll ans;int n,m,tot,cur[maxn],cnt,root[maxn],mx;struct node{ int left,right,sizee; ll sum;}e[maxn * 25];struct node2{ int pos,val;}a[maxn];bool cmp(node2 a,node2 b){ return a.pos < b.pos;}void update(int l,int r,int x,int &y,int v){ e[y = ++cnt] = e[x]; e[y].sizee += (v > 0 ? 1 : -1); e[y].sum += v; if (l == r) return; int mid = (l + r) >> 1; if (abs(v) <= mid) update(l,mid,e[x].left,e[y].left,v); else update(mid + 1,r,e[x].right,e[y].right,v);}ll query(int l,int r,int x,int k){ if (e[x].sizee <= k) return e[x].sum; if (l == r) return 1LL * l * k; int mid = (l + r) >> 1; if (k <= e[e[x].left].sizee) return query(l,mid,e[x].left,k); else return e[e[x].left].sum + query(mid + 1,r,e[x].right,k - e[e[x].left].sizee);}int main(){ scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); a[++tot].pos = x; a[tot].val = z; a[++tot].pos = y + 1; a[tot].val = -z; mx = max(mx,z); } sort(a + 1,a + 1 + tot,cmp); for (int i = 1; i <= tot; i++) update(1,mx,root[i - 1],root[i],a[i].val); for (int i = tot; i >= 1; i--) //维护每一个被更改的时间点最后在哪里被更改的 if (a[i].pos != a[i + 1].pos) cur[a[i].pos] = root[i]; for (int i = 1; i <= m; i++) //如果当前时间点没有被更改,那么就和前一个时间点的情况一样 if (!cur[i]) cur[i] = cur[i - 1]; ans = 1; for (int i = 1; i <= m; i++) { ll t,x,y,z,k; scanf("%lld%lld%lld%lld",&t,&x,&y,&z); k = (1LL * x * ans + y) % z + 1; ans = query(1,mx,cur[t],k); printf("%lld\n",ans); } return 0;}

 

转载于:https://www.cnblogs.com/zbtrs/p/8279942.html

你可能感兴趣的文章
aboutMe
查看>>
【Debug】IAR在线调试时报错,Warning: Stack pointer is setup to incorrect alignmentStack,芯片使用STM32F103ZET6...
查看>>
一句话说清分布式锁,进程锁,线程锁
查看>>
Hash和Bloom Filter
查看>>
SQL Server获取月度列表
查看>>
python常用函数
查看>>
python 描点画圆
查看>>
FastDFS使用
查看>>
服务器解析请求的基本原理
查看>>
pycharm 如何设置方法调用字体颜色
查看>>
VUE源码解析心得
查看>>
[HDU3683 Gomoku]
查看>>
【工具相关】iOS-Reveal的使用
查看>>
整体二分——[Poi2011]Meteors
查看>>
数据库3
查看>>
delphi之事件
查看>>
windows server 2008 r2 安装
查看>>
存储分类
查看>>
下一代操作系统与软件
查看>>
【iOS越狱开发】如何将应用打包成.ipa文件
查看>>