• BZOJ3932 [CQOI2015]任务查询系统 主席树


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ3932


    题意概括

      电脑有N个任务需要执行,任务i在li到ri时正在工作,优先级为p。 现在给出M个询问,每个询问给出一个时间点xi和一个数ki。问在xi这个时间点时,所有正在工作的任务中优先级从小到大排列,前ki个的优先级之和是多少。 强制在线。 N<=100 000,M<=100 000


    题解

      用差分的思想,在Li的地方加,在Ri的地方减。

      然后就是裸的主席树。

      有坑。

      这题细节丧病。

      首先,我把n和m反着写,然后还以为时间点是n(我的n),事实上是我的m。

      其次,还会出现同一个时间点多个事件,要考虑,所以对于长度为1的区间,要sum/size*k

      当然,事情还没有结束。

      size有可能是0,要特判。


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    int n,m,Ha[N],hs;
    vector <int> tz[N];
    struct Task{
    	int L,R,P;
    	void Read(){
    		scanf("%d%d%d",&L,&R,&P);
    	}
    }t[N];
    void LSH(){
    	int hs_=1;
    	sort(Ha+1,Ha+hs+1);
    	for (int i=2;i<=hs;i++)
    		if (Ha[i]!=Ha[i-1])
    			Ha[++hs_]=Ha[i];
    	hs=hs_;
    }
    const int S=N*4*20;
    int ls[S],rs[S],size[S],total,root[N];
    LL sum[S];
    int find(int v){
    	return lower_bound(Ha+1,Ha+hs+1,v)-Ha;
    }
    void build(int &rt,int L,int R){
    	rt=++total;
    	if (L==R)
    		return;
    	int mid=(L+R)>>1;
    	build(ls[rt],L,mid);
    	build(rs[rt],mid+1,R);
    }
    void add(int prt,int &rt,int L,int R,int pos,LL v,int op){
    	if (!rt||rt==prt)
    		rt=++total,sum[rt]=sum[prt],size[rt]=size[prt];
    	sum[rt]+=v,size[rt]+=op;
    	if (L==R)
    		return;
    	int mid=(L+R)>>1;
    	if (!ls[rt])
    		ls[rt]=ls[prt];
    	if (!rs[rt])
    		rs[rt]=rs[prt];
    	if (pos<=mid)
    		add(ls[prt],ls[rt],L,mid,pos,v,op);
    	else
    		add(rs[prt],rs[rt],mid+1,R,pos,v,op);
    }
    LL query(int rt,int L,int R,int k){
    	if (L==R){
    		k=min(k,size[rt]);
    		if (size[rt]==0)
    			return 0;
    		return sum[rt]*k/size[rt];
    	}
    	int Lz=size[ls[rt]];
    	int mid=(L+R)>>1;
    	if (Lz>=k)
    		return query(ls[rt],L,mid,k);
    	else
    		return sum[ls[rt]]+query(rs[rt],mid+1,R,k-Lz);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++){
    		t[i].Read();
    		Ha[i]=t[i].P;
    	}
    	hs=n;
    	LSH();
    	for (int i=1;i<=m+1;i++)
    		tz[i].clear();
    	for (int i=1;i<=n;i++){
    		tz[t[i].L].push_back(i);
    		tz[t[i].R+1].push_back(i);
    		t[i].P=find(t[i].P);
    	}
    	total=0;
    	build(root[0],1,hs);
    	for (int i=1;i<=m;i++){
    		root[i]=root[i-1];
    		for (int j=0;j<tz[i].size();j++){
    			int k=tz[i][j];
    			if (t[k].L==i)
    				add(root[i-1],root[i],1,hs,t[k].P,Ha[t[k].P],1);
    			else
    				add(root[i-1],root[i],1,hs,t[k].P,-Ha[t[k].P],-1);
    		}
    	}
    	LL pre=1;
    	for (int i=1;i<=m;i++){
    		int x,A,B,C,k;
    		scanf("%d%d%d%d",&x,&A,&B,&C);
    		k=(pre*A+B)%C+1;
    		printf("%lld
    ",pre=query(root[x],1,hs,k));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    python字符串与字典转换
    B站弹幕爬取 / jieba分词
    【计算机网络】第四章 网络层(1)
    【计算机网络】第三章 传输层(4)
    【计算机网络】第三章 传输层(3)
    【计算机网络】第三章 传输层(2)
    【计算机网络】第三章 传输层(1)
    【计算机网络】第二章 网络应用(5)
    【计算机网络】第二章 网络应用(4)
    【计算机网络】第二章 网络应用(3)
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3932.html
Copyright © 2020-2023  润新知