BZOJ 3932 [CQOI2015]任务查询系统 可持久化线段树
2016-01-04 21:35
441 查看
以时间戳划分,每个时间点维护一个线段树,任务开始时在对应权值处+1,结束后-1就好啦。上可持久化线段树。
感觉分配内存还是动态一大段一大段分比较好。。RE了才知道要调大数组。
Submit: 912 Solved: 335
[Submit][Status][Discuss]
超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同。调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。
接下来m行,每行包含三个空格分开的正整数Si、Ei和Pi(Si≤Ei),描述一个任务。
接下来n行,每行包含四个空格分开的整数Xi、Ai、Bi和Ci,描述一次查询。查询的参数Ki需要由公式 Ki=1+(Ai*Pre+Bi) mod Ci
计算得到。其中Pre表示上一次查询的结果,对于第一次查询,Pre=1。
1 2 6
2 3 3
1 3 2
3 3 4
3 1 3 2
1 1 3 4
2 2 4 3
8
11
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的一个排列
感觉分配内存还是动态一大段一大段分比较好。。RE了才知道要调大数组。
#include <cstdio> #include <algorithm> using namespace std; const int M = 100001; typedef long long ll; struct Tree { Tree *lc, *rc; int sz; ll sum; Tree() { lc = rc = this; sum = sz = 0; } Tree(Tree *_lc, Tree *_rc, int _sz, ll _sum) : lc(_lc), rc(_rc), sz(_sz), sum(_sum) { } void *operator new(size_t) { static Tree pool[M * 60], *pointer = pool; return pointer++; } static Tree *insert(Tree *t, int l, int r, int x, int sz, ll sum) { ll mid = l + r >> 1; if (l == r) return new Tree(NULL, NULL, t->sz + sz, t->sum + sum); else if (x <= mid) return new Tree(insert(t->lc, l, mid, x, sz, sum), t->rc, t->sz + sz, t->sum + sum); else return new Tree(t->lc, insert(t->rc, mid + 1, r, x, sz, sum), t->sz + sz, t->sum + sum); } static ll get(Tree *t, int l, int r, int k) { ll mid = l + r >> 1; if (l == r) return mid * min(k, t->sz); if (k <= t->lc->sz) return get(t->lc, l, mid, k); else return get(t->rc, mid + 1, r, k - t->lc->sz) + t->lc->sum; } } *tree[M]; struct Task { int state, ts, priority; friend bool operator <(const Task &a, const Task &b) { return a.ts < b.ts; } } tasks[M * 2]; int main() { const int ARRAY_SIZE = 10000000; int i, j, n, m, x, s, e, p; ll pre = 1; scanf("%d%d", &m, &n); for (i = 1; i <= m; i++) { scanf("%d%d%d", &s, &e, &p); tasks[i * 2 - 1] = (Task) {1, s, p}; tasks[i * 2] = (Task) {-1, e + 1, p}; } sort(tasks + 1, tasks + m * 2 + 1); tree[0] = new Tree(); for (i = j = 1; i <= n; i++) { tree[i] = tree[i - 1]; for (; j <= m * 2 && tasks[j].ts == i; j++) tree[i] = Tree::insert(tree[i], 1, ARRAY_SIZE, tasks[j].priority, tasks[j].state, tasks[j].priority * tasks[j].state); } for (i = 1; i <= n; i++) { scanf("%d%d%d%d", &x, &s, &e, &p); int k = (s * pre + e) % p + 1; printf("%lld\n", pre = Tree::get(tree[x], 1, ARRAY_SIZE, k)); } return 0; }
3932: [CQOI2015]任务查询系统
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 912 Solved: 335
[Submit][Status][Discuss]
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 31 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
28
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的一个排列
相关文章推荐
- 总理火了3W咖啡,下一个火的在哪儿
- linux c中自编的一个进制(2~36进制)转换函数(strtol库函数自带,ltostr自编)
- TCP与SOCKET的三次握手的对应关系
- 数据库学习知识点
- 分部
- hdu 3033 I love sneakers! 分组背包
- JavaScript:理解constructor
- 机器学习(四):分类算法之朴素贝叶斯
- UE4 Hello World 创建第一个UE4工程
- UE4 Hello World 创建第一个UE4工程
- javascript--出错与调试
- Socket的综合应用总结
- nginx 或tengine 访问日志分割处理
- Spring中 <tx:advice/> 标签
- IOS 委托代理(delegate)实现页面传值
- 数据库第四章
- iOS动态启动界面(swift实现)
- Ubuntu安装g++
- iOS开发之基础控件(Swift版)
- 2016新年第一记