zoukankan      html  css  js  c++  java
  • Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals

    题目连接:

    http://codeforces.com/gym/100231/attachments

    Description

    给你n个区间,告诉你每个区间内都有ci个数

    然后你需要找一个最小的点集,使得满足这n个区间的条件

    Input

    n

    然后li,ri,ci

    Output

    输出最小点集大小

    Sample Input

    5

    3 7 3

    8 10 3

    6 8 1

    1 3 1

    10 11 1

    Sample Output

    6

    Hint

    题意

    题解:

    线段树+二分+贪心

    首先我们贪心一发,按照右端点排序之后,我们点肯定是优先放在右边

    那么我们怎么确认有多少个放右边呢?

    二分+线段树就好了,我们二分有多少个点放在右边,然后在用线段树的区间和来check是否大于ci就好了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef int SgTreeDataType;
    struct treenode
    {
      int L , R  ;
      SgTreeDataType sum , lazy;
      void updata(SgTreeDataType v)
      {
          sum = (R-L+1)*v;
      	lazy = v;
      }
    };
    
    treenode tree[301500];
    
    inline void push_down(int o)
    {
    	SgTreeDataType lazyval = tree[o].lazy;
    	if(lazyval!=0){
    	tree[2*o].updata(lazyval) ; tree[2*o+1].updata(lazyval);
    	tree[o].lazy = 0;
    	}
    }
    
    inline void push_up(int o)
    {
    	tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;
    }
    
    inline void build_tree(int L , int R , int o)
    {
    	tree[o].L = L , tree[o].R = R,tree[o].sum = tree[o].lazy = 0;
    	if (R > L)
    	{
    		int mid = (L+R) >> 1;
    		build_tree(L,mid,o*2);
    		build_tree(mid+1,R,o*2+1);
    	}
    }
    
    inline void updata(int QL,int QR,SgTreeDataType v,int o)
    {
        if(QL>QR)return;
    	int L = tree[o].L , R = tree[o].R;
    	if (QL <= L && R <= QR) tree[o].updata(v);
    	else
    	{
    		push_down(o);
    		int mid = (L+R)>>1;
    		if (QL <= mid) updata(QL,QR,v,o*2);
    		if (QR >  mid) updata(QL,QR,v,o*2+1);
    		push_up(o);
    	}
    }
    
    inline SgTreeDataType query(int QL,int QR,int o)
    {
        if(QL>QR)return 0;
    	int L = tree[o].L , R = tree[o].R;
    	if (QL <= L && R <= QR) return tree[o].sum;
    	else
    	{
    		push_down(o);
    		int mid = (L+R)>>1;
    		SgTreeDataType res = 0;
    		if (QL <= mid) res += query(QL,QR,2*o);
    		if (QR > mid) res += query(QL,QR,2*o+1);
    		push_up(o);
    		return res;
    	}
    }
    
    struct node
    {
        int l,r,c;
    }p[52000];
    bool cmp(node a,node b)
    {
        if(a.r==b.r&&a.l==b.l)
            return a.c<b.c;
        if(a.r==b.r)
            return a.l>b.l;
        return a.r<b.r;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].c);
            p[i].l+=1,p[i].r+=1;
        }
        sort(p+1,p+1+n,cmp);
        build_tree(1,p[n].r+100,1);
        int ans = 0;
        for(int i=1;i<=n;i++)
        {
            //int now = query(p[i].l,p[i].r,1);
            //if(now<p[i].c)
            //{
            int L = p[i].l-1,R = p[i].r;
            while(L<=R)
            {
                int mid = (L+R)/2;
                if(query(p[i].l,mid,1)+(p[i].r-mid)>=p[i].c)
                    L=mid+1;
                else
                    R=mid-1;
            }
            ans+=(p[i].r-L+1)-query(L,p[i].r,1);
            //cout<<L<<" "<<p[i].r<<endl;
            updata(L,p[i].r,1,1);
            //}
        }
        //for(int i=1;i<=p[n].r;i++)
        //    cout<<query(i,i,1)<<" ";
        //cout<<endl;
        cout<<ans<<endl;
    }
    /*
    5
    3 7 3
    8 10 3
    6 8 1
    1 3 1
    10 11 1
    */
  • 相关阅读:
    Android视频播放软解与硬解的区别
    Android ViewPager嵌套ViewPager滑动冲突处理方法
    2.2 Consumer API官网剖析(博主推荐)
    2.1 Producer API官网剖析(博主推荐)
    2. APIS官网剖析(博主推荐)
    1.5 Upgrading From Previous Versions官网剖析(博主推荐)
    1.4 Ecosystem官网剖析(博主推荐)
    1.3 Quick Start中 Step 8: Use Kafka Streams to process data官网剖析(博主推荐)
    1.3 Quick Start中 Step 7: Use Kafka Connect to import/export data官网剖析(博主推荐)
    1.3 Quick Start中 Step 6: Setting up a multi-broker cluster官网剖析(博主推荐)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5134445.html
Copyright © 2011-2022 走看看