【BZOJ 3932】[CQOI2015]任务查询系统
2017-04-26 08:32
288 查看
题目来源:BZOJ 3932
思路:
类似于在区间上标记线段的操作,把所有的区间变成两个点,边操作边进行前缀和就好了,需要用用主席树维护的信息有权值的出现次数,权值的和。特别注意,在处理答案的时候,最后一个节点可能有多种状态,有可能只选择其中的一部分,需要特判一下。
代码:
#include <iostream> #include <cstdio> #include <algorithm> #define mid ((l+r)>>1) using namespace std; const int maxn = 100010; typedef long long ll; struct node{ int time, val; bool operator < (const node &tt)const{return time < tt.time;} } p[maxn*2]; struct Tree{ int num, sum; Tree *ch[2]; } T[maxn*40], *root[maxn*2]; int n, m, cnt, nxt, ct, _tm; int val[maxn], last[maxn], tm[maxn]; ll Pre = 1; ll gt(){ char c = ' '; ll num = 0; bool ok = 0; while(1){ c = getchar(); if(c <= '9' && c >= '0') num = num * 10 + c - '0', ok = 1; else if(ok) return num; } } int find(int ee[], int l, int r, int v){ int ans = 0; while(l <= r){ if(ee[mid] <= v) ans = mid, l = mid + 1; else r = mid - 1; } return ans; } int abs(int x){return x < 0 ? -x : x;} Tree* get(){return &T[++nxt];} void made(Tree* now, int l, int r){ if(l == r) return; made(now->ch[0] = get(), l, mid); made(now->ch[1] = get(), mid+1, r); } void build(Tree* now, Tree* pre, int k, int Num, int Sum, int l, int r){ if(l == r) < 4000 span class="hljs-keyword">return; int wh = 1; if(k <= mid) wh = 0; now->ch[wh^1] = pre->ch[wh^1]; now->ch[wh] = get(); now->ch[wh]->num = pre->ch[wh]->num + Num; now->ch[wh]->sum = pre->ch[wh]->sum + Sum; build(now->ch[wh], pre->ch[wh], k, Num, Sum, wh == 0 ? l : mid+1, wh == 0 ? mid : r); } ll ask(Tree* now, int k, int l, int r){ if(l == r){ // 这里特判。 if(now->num) return now->sum / now->num * k; return now->sum; } if(k <= now->ch[0]->num) return ask(now->ch[0], k, l, mid); else return now->ch[0]->sum + ask(now->ch[1], k-now->ch[0]->num, mid+1, r); } int main(){ scanf("%d%d", &m, &n); for(int i = 1; i <= m; i ++){ int a = gt(), b = gt(), c = gt(); p[++cnt].time = a, p[cnt].val = c; p[++cnt].time = b+1, p[cnt].val = -c; val[++ct] = c; } // 按时间排序 sort(p+1, p+1+cnt); // 离散化 sort(val+1, val+1+ct); ct = unique(val+1, val+1+ct) - (val+1); // 建树 root[0] = get(); made(root[0], 1, ct); for(int i = 1; i <= cnt; i ++){ last[p[i].time] = i; int pos = find(val, 1, ct, abs(p[i].val)); root[i] = get(); build(root[i], root[i-1], pos, p[i].val > 0 ? 1:-1, p[i].val, 1, ct); } for(int i = 1; i <= n; i ++) if(last[i] != 0) tm[++_tm] = i; // 查询 for(int i = 1; i <= n; i ++){ ll ti = gt(), a = gt(), b = gt(), c = gt(), ki; ti = tm[find(tm, 1, _tm, ti)]; ki = (((a%c)*(Pre%c))%c+(b%c))%c + 1; Pre = ask(root[last[ti]], ki, 1, ct); printf("%lld\n", Pre); } return 0; }
相关文章推荐
- [BZOJ3932] [CQOI2015]任务查询系统 && 可持久化线段树
- bzoj 3932 [CQOI2015]任务查询系统(主席树)
- Bzoj3932--Cqoi2015任务查询系统
- 【BZOJ3932】[CQOI2015]任务查询系统 主席树
- 【BZOJ 3932】[CQOI2015]任务查询系统 主席树
- [BZOJ3932][CQOI2015]任务查询系统(主席树||树状数组套主席树)
- [主席树] BZOJ 3932 [CQOI2015]任务查询系统
- bzoj 3932 [CQOI2015]任务查询系统 可持久化二维线段树
- 【主席树】BZOJ3932-[CQOI2015]任务查询系统
- BZOJ 3932 [CQOI2015] 任务查询系统 可持久化线段树
- BZOJ 3932 CQOI2015 任务查询系统 可持久化线段树
- Bzoj 3932: [CQOI2015]任务查询系统(主席树)
- bzoj3932 [CQOI2015]任务查询系统
- [BZOJ3932]CQOI2015任务查询系统|主席树
- bzoj 3932: [CQOI2015]任务查询系统
- bzoj3932【CQOI2015】任务查询系统
- [BZOJ 3932][CQOI 2015]任务查询系统
- BZOJ 3932 CQOI 2015 任务查询系统 可持久化线段树
- BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树
- bzoj 3932: [CQOI2015]任务查询系统 可持久化纤段树