zoukankan      html  css  js  c++  java
  • CF1070C Solution

    题目链接

    题解

    可以想到,这道题需要维护每日的内核数,并利用贪心思想找出该日价值从小到大的前(k)个内核。第一想法是优先队列+二分,但无法处理出队,于是卡住了(# -_ゝ-)。此后阅读了一篇题解,发现可以使用权值线段树。

    线段树中维护当日每个价值的内核个数(因为(p_ile 10^6),不需要离散化),提前存储每日的变动(vector和链式前向星均可),进行单点修改即可。至于查询更像是树上二分,寻找第(k)个内核所在节点与小于其的价值总和:设(t)为当前节点需要查找的内核个数,如果左儿子的内核数(le t),则递归左儿子;反之则说明最接近(k)的节点,加上左儿子的总价值,递归右儿子。

    最终答案(=)每日花费总和。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e6+10;
    struct node {int l,r,num,v;} tr[4*N];//tr[i].num:i号节点的内核个数,tr[i].v:i号节点的内核总价值 
    int l[N],r[N],c[N],p[N]; 
    vector<int> st[N],ed[N];//st[i]:从i日开始的方案,ed[i]:至i日结束的方案
    void build(int x,int l,int r)
    {
    	tr[x].l=l; tr[x].r=r;
    	if(l==r) return;
    	int mid=(l+r)/2;
    	build(x*2,l,mid); build(x*2+1,mid+1,r);
    }
    void add(int x,int pos,int d)
    {
    	if(tr[x].l==tr[x].r) 
    	{
    		tr[x].num+=d; tr[x].v+=d*tr[x].l;
    		return;
    	}
    	int mid=(tr[x].r+tr[x].l)/2;
    	if(pos<=mid) add(x*2,pos,d);
    	else add(x*2+1,pos,d);
    	tr[x].num=tr[x*2].num+tr[x*2+1].num;
    	tr[x].v=tr[x*2].v+tr[x*2+1].v;
    }
    int query(int x,int k)//(此处k同上文中的t)
    {
        //如果当前内核个数大于t,或总个数不足k时,取较小值
    	if(tr[x].l==tr[x].r) return min(tr[x].num,k)*tr[x].l;
    	if(k<=tr[x*2].num) return query(x*2,k);
    	else return tr[x*2].v+query(x*2+1,k-tr[x*2].num);
    }
    signed main()
    {
    	int n,m,k,ans=0,maxn=0;
    	scanf("%lld%lld%lld",&n,&k,&m);
    	for(int i=1;i<=m;i++) 
    	{
    		scanf("%lld%lld%lld%lld",&l[i],&r[i],&c[i],&p[i]);
    		st[l[i]].push_back(i); ed[r[i]].push_back(i);
    		maxn=max(maxn,p[i]);
    	}
    	build(1,1,maxn);
    	for(int i=1;i<=n;i++)
    	{
            //因为含r[i],所以先统计答案再处理结束的方案
    		int siz=st[i].size();
    		for(int j=0;j<siz;j++) add(1,p[st[i][j]],c[st[i][j]]);
    		ans+=query(1,k);
    		siz=ed[i].size();
    		for(int j=0;j<siz;j++) add(1,p[ed[i][j]],-c[ed[i][j]]);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    php socket 读取缓存区域
    PHP依赖注入的作用
    谷歌浏览器调试文字都变成font标签的解决方法
    php socket 同步异步堵塞非堵塞的区别
    css3中background-size中的cover与contain的区别
    css3 line-height:0的作用
    RDD的创建方式
    Serializable序列化操作解惑
    SparkCore分布式计算模拟
    spark不同环境下计算pi值
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14317147.html
Copyright © 2011-2022 走看看