bzoj3932 & 洛谷P3168 [CQOI2015] 任务查询系统 差分+主席树

题目链接:
洛谷3168
bzoj3932

在区间 [ S i , E i ] [S_i,E_i] [Si,Ei]内添加一个优先级为 P i P_i Pi的任务 —— 区间修改
查询时刻 x x x时前 k k k个优先级之和 ——单点查询
区间修改,单点查询,因此想到差分。查询前 k k k个数之和,想到主席树。
差分时,把 [ S i , E i ] [S_i,E_i] [Si,Ei]的区间转化为在 S i S_i Si + 1 +1 +1,在 E i E_i Ei − 1 -1 1
主席树中维护两个值: n u m [ r t ] num[rt] num[rt]表示以 r t rt rt为根的主席树中有多少个数在区间内。
s u m [ r t ] sum[rt] sum[rt]表示以 r t rt rt为根的主席树的所有值的和。
然后 u p d a t e update update时分别维护,查询就是普通的求和操作。

毒瘤代码

#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include<vector>
#define re register int
#define rl register ll
using namespace std;
typedef long long ll;
ll read() {
	rl x=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9') {
		if(ch=='-')	f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9') {
		x=10*x+ch-'0';
		ch=getchar();
	}
	return x*f;
}
namespace I_Love {

const int Size=200005;
const int LOG=20;
struct Task {
	int x; ll p;
} w[Size];
int n,m,maxn,tot,T[Size];
int ls[Size*LOG],rs[Size*LOG],num[Size*LOG];
ll a[Size],sum[Size*LOG];
int update(int pre,int l,int r,int x,int v,ll pri) {
	int rt=++tot;
	ls[rt]=ls[pre]; rs[rt]=rs[pre];
	num[rt]=num[pre]+v;
	sum[rt]=sum[pre]+pri;
	if(l<r) {
		int mid=(l+r)>>1;
		if(x<=mid) {
			ls[rt]=update(ls[pre],l,mid,x,v,pri);
		} else {
			rs[rt]=update(rs[pre],mid+1,r,x,v,pri);
		}
	}
	return rt;
}
ll query(int l,int r,ll k,int rt) {
	if(l==r)	return a[l]*k;
	int mid=(l+r)>>1,x=num[ls[rt]];
	if(k<=x)	return query(l,mid,k,ls[rt]);
	return sum[ls[rt]]+query(mid+1,r,k-x,rs[rt]);
}
inline bool comp(Task jzm,Task xjp) {
	return jzm.x<xjp.x;
}
void Fujibayashi_Ryou() {
	m=read();
	n=read();
	for(re i=1; i<=m; i++) {
		w[i].x=read();
		w[i+m].x=read()+1;
		a[i]=w[i].p=read();
		w[i+m].p=-w[i].p;
	}
	sort(a+1,a+1+m);
	maxn=unique(a+1,a+1+m)-(a+1);
	int pos=1;
	sort(w+1,w+1+(m<<1),comp);
	for(int i=1; i<=(m<<1); i++) {
		for(re j=w[i-1].x+1; j<=w[i].x; j++)	T[j]=T[j-1];
		int tmp=lower_bound(a+1,a+1+maxn,abs(w[i].p))-a;
		if(w[i].p>0) {
			T[w[i].x]=update(T[w[i].x],1,maxn,tmp,1,w[i].p);
		} else {
			T[w[i].x]=update(T[w[i].x],1,maxn,tmp,-1,w[i].p);
		}
	}
	ll pre=1;
	for(re i=1; i<=n; i++) {
		ll x=read();
		ll A=read();
		ll B=read();
		ll C=read();
		ll k=(A*pre+B)%C+1ll;
		if(num[T[x]]<=k) {
			printf("%lld\n",pre=sum[T[x]]);
		} else {
			printf("%lld\n",pre=query(1,maxn,k,T[x]));
		}
	}
}

}
int main() {
	I_Love::Fujibayashi_Ryou();
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值