[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;
}

  

posted @ 2018-10-19 16:02  EM-LGH  阅读(137)  评论(0编辑  收藏  举报