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


    题目描述

    这不是个链接


    思路分析

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

    因为 (p_ileq10^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
    ",ans);
    	}
    	return 0;	
    }
    
  • 相关阅读:
    windows程序中的数据绑定
    dbhelper
    数据库错题
    构建布局良好的windows程序
    初始windows程序
    asp.net 文件下载 解决文件名乱码
    asp.net 文件下载 文件名称乱码 处理~~
    ASP.NET上传文件并记录到数据库
    Jquery配合Asp.Net无刷新删除指定服务器上的文件!
    Frame、Iframe、Frameset 的区别
  • 原文地址:https://www.cnblogs.com/hhhhalo/p/14020182.html
Copyright © 2020-2023  润新知