[CQOI2015]任务查询系统 主席树_差分
Code:
#include<vector> #include<cstdio> #include<algorithm> #include<string> #include<iostream> #include<cstring> using namespace std; void SetIO(string a){ string in = a + ".in"; freopen(in.c_str(), "r", stdin); } const int maxn = 100000 + 4; struct Task{ int st, ed, val; Task(int st = 0, int ed = 0, int val = 0):st(st), ed(ed), val(val){} }task[maxn]; int Sorted[maxn]; int n, m; void Read(){ scanf("%d%d",&m,&n); for(int i = 1;i <= m; ++i) { int a, b, c; scanf("%d%d%d",&a,&b,&c); task[i] = Task(a, b, c); Sorted[i] = task[i].val; } } struct Type{ int delta, val; Type(int delta=0, int val=0):delta(delta), val(val){} }; vector<Type>G[maxn]; void Disperse(){ sort(Sorted + 1, Sorted + 1 + m); for(int i = 1;i <= m; ++i){ task[i].val = lower_bound(Sorted + 1, Sorted + 1 + m, task[i].val) - Sorted; G[task[i].st].push_back(Type(1, task[i].val)); G[task[i].ed + 1].push_back(Type(-1, task[i].val)); } } const int Tree_const = 50; int numv[maxn * Tree_const], root[maxn]; long long sumv[maxn * Tree_const]; struct Chair_Tree{ int lson[maxn * Tree_const], rson[maxn * Tree_const], cnt_Tree; void build(int l, int r, int &o){ if(l > r) return ; o = ++cnt_Tree; if(l == r) return ; int mid = (l + r) >> 1; build(l, mid, lson[o]); build(mid + 1, r, rson[o]); } int insert(int l, int r, int o, int pos, int delta){ int oo = ++cnt_Tree; lson[oo] = lson[o]; rson[oo] = rson[o]; numv[oo] = numv[o] + delta; sumv[oo] = sumv[o] + delta * Sorted[pos]; int mid = (l + r) >> 1; if(l == r) return oo; if(pos <= mid) lson[oo] = insert(l, mid, lson[o], pos, delta); else rson[oo] = insert(mid + 1, r, rson[o], pos, delta); return oo; } long long query(int l, int r, int cur, int k){ if(l == r) return k * Sorted[l]; int lnum = numv[lson[cur]] ; int mid = (l + r) >> 1; if(k <= lnum) return query(l, mid,lson[cur], k); else return sumv[lson[cur]] + query(mid + 1, r, rson[cur], k - lnum); } }Tree; void Build(){ Tree.build(1, m, root[0]); for(int i = 1;i <= n; ++i){ int siz = G[i].size(); int rt = root[i - 1]; for(int j = 0;j < siz; ++j){ rt = Tree.insert(1, m, rt, G[i][j].val, G[i][j].delta); } root[i] = rt; } } void Init(){ Read(); Disperse(); Build(); } void Work(){ long long pre = 1; for(int i = 1;i <= n; ++i){ int x, k, a, b, c; scanf("%d%d%d%d",&x,&a,&b,&c); k = 1 + (a * pre + b) % c; if(numv[root[x]] < k) pre = sumv[root[x]] ; else pre = Tree.query(1, m, root[x], k); printf("%lld\n", pre); } } int main(){ SetIO("input"); Init(); Work(); return 0; }