[CQOI2015]任務查詢系統 主席樹_差分
阿新 • • 發佈:2018-12-16
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;
}