任务查询系统「主席树+差分」

题目描述

这不是个链接


思路分析

\(k\) 小,主席树经典问题,稍微有一点不同的就是这题要求的是前 \(k\) 个的总和,但其实并没什么区别,只需要在线段树中分别记录个数和 \(sum\) 就好了。

因为 \(p_i\leq10^7\),所以需要离散化。

对于每一个任务,由于生效时间是一个区间,所以可以差分,即对于每个任务对应的区间,拆成两个点,在 \(l\)\(+1\),在 \(r+1\)\(-1\)

另外由于将每个区间拆成了两个点,所以空间需要比一般的主席树再多开一倍。


\(Code\)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#define N 100010
#define R register
#define ll long long
using namespace std;
inline int read(){
	int x = 0,f = 1;
	char ch = getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int cnt,ls[N<<6],rs[N<<6],b[N],a[N],n,m,root[N<<6];
ll ans = 1;
struct Segment_tree{
	ll sum;
	int cnt;
}tr[N<<6];
vector<int>s[N],t[N];
void modify(int &rt,int l,int r,int pre,int aim,int val){
	rt = ++cnt;
	tr[rt] = tr[pre];
	ls[rt] = ls[pre],rs[rt] = rs[pre];
	tr[rt].cnt += val,tr[rt].sum += 1ll*val*b[aim];
	if(l==r)return;
	int mid = (l+r)>>1;
	if(aim<=mid)modify(ls[rt],l,mid,ls[pre],aim,val);
	else modify(rs[rt],mid+1,r,rs[pre],aim,val);
}
ll query(int rt,int l,int r,int k){
	if(l==r)return 1ll*b[l]*k;
	int mid = (l+r)>>1;
	int tmp = tr[ls[rt]].cnt;
	if(k<=tmp)return query(ls[rt],l,mid,k);
	else return query(rs[rt],mid+1,r,k-tmp)+tr[ls[rt]].sum;
}
int main(){
	m = read(),n = read();
	for(R int i = 1;i <= m;i++){
		int x = read(),y = read();
		b[i] = a[i] = read();
		s[x].push_back(i),t[y+1].push_back(i);
	}
	sort(b+1,b+1+m);
	int tot = unique(b+1,b+1+m)-(b+1);
	for(R int i = 1;i <= n;i++){
		root[i] = root[i-1];
		for(R int j = 0;j < s[i].size();j++){
			int tmp = lower_bound(b+1,b+1+tot,a[s[i][j]])-b;
			modify(root[i],1,tot,root[i],tmp,1);
		}
		for(R int j = 0;j < t[i].size();j++){
			int tmp = lower_bound(b+1,b+1+tot,a[t[i][j]])-b;
			modify(root[i],1,tot,root[i],tmp,-1);
		}
	}
	for(R int i = 1;i <= n;i++){
		int x = read(),ai = read(),bi = read(),ci = read();
		int k = 1+(1ll*ai*ans+bi)%ci;
		if(k>tr[root[x]].cnt)ans = tr[root[x]].sum;
		else ans = query(root[x],1,tot,k);
		printf("%lld\n",ans);
	}
	return 0;	
}
posted @ 2020-11-22 17:55  HH_Halo  阅读(112)  评论(0编辑  收藏  举报