zoukankan      html  css  js  c++  java
  • CF1260D A Game with Traps

    http://codeforces.com/problemset/problem/1260/D
    首先很明显可以想到二分答案,把能力值数组排个序就好。
    考虑怎么check。
    设当前二分值为w,即不能直接跨过权值>w的陷阱。
    将所有的陷阱按l升序排列。可以发现,如果两个或多个
    陷阱重叠,肯定是这个人直接从这几个陷阱最小的l走到
    最大的r最优。
    证明?这里只给出两个区间重叠的情况。
    假设两个区间分别为[a,b],[c,d],a<c<b<d。
    想把队伍从a带到d,第一种的总时间为3(d-a);如果是a->c
    ->a->b->d->c->d,总耗时是3(c-a)+3(d-b)-(c-b)
    =3d+2c-2b-3a>3d-3a。
    用双指针模拟就好。

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    #define I inline void
    #define IN inline int
    typedef long long ll;
    I read(int &res){
        re g=1;register char ch=getchar();res=0;
        while(!isdigit(ch)){
            if(ch=='-')g=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            res=(res<<3)+(res<<1)+(ch^48);
            ch=getchar();
        }
        res*=g;
    }
    int n,m,k,t,p,q,X,Y,sum,lim,a[202000];
    inline bool bbb(int x,int y){
    	return x>y;
    }
    struct Barrier{
    	int l,r,w;
    	friend bool operator < (Barrier x,Barrier y){
    		return x.l==y.l?x.r<y.r:x.l<y.l;
    	}
    }b[202000];
    IN ck(int x){
    	if(!x)return 1;
    	sum=0;
    	lim=a[x];
    	p=1;
    	while(p<=k&&b[p].w<=lim)p++;
    	if(p>k)X=sum=0;
    	else sum=X=b[p].l-1;
    	while(p<=k){
    		Y=b[p].r;
    		q=p+1;
    		while(q<=k&&(b[q].w<=lim||b[q].l<=Y)){
    			if(b[q].w>lim)Y=max(Y,b[q].r);
    			q++;
    		}
    		sum+=3*(Y-X);
    		X=Y;
    		if(q>k)break;
    		sum+=(b[q].l-1-X);
    		X=b[q].l-1;
    		p=q;
    	}
    	sum+=(m-X);
    	//cout<<x<<" "<<sum<<endl;
    	if(sum<=t)return 1;
    	return 0;
    }
    IN divided(int x,int y){
    	if(x==y)return x;
    	re mid=(x+y+1)>>1;
    	if(ck(mid))x=mid;
    	else y=mid-1;
    	return divided(x,y);
    }
    int main(){
    	read(n);read(m);read(k);read(t);m++;
    	F(i,1,n){
    		read(a[i]);
    	}
    	sort(a+1,a+1+n,bbb);
    	F(i,1,k){
    		read(b[i].l);read(b[i].r);read(b[i].w);
    	}
    	sort(b+1,b+1+k);
    	b[k+1].l=0;
    	if(m>t){
    		cout<<"0";
    		return 0;
    	}
    	cout<<divided(0,n);
        return 0;
    }
    
  • 相关阅读:
    四川省选2012 day1 喵星球上的点名 (后缀数组,并不是完全的正解)
    6.2.1 最短路
    5.3.3 敌兵布阵
    6.1.1 Constructing Roads
    6.2.4 Arbitrage
    6.1.6 Jungle Roads
    5.3.6 Cow Sorting (HDU 及 POJ)
    6.2.5 Trucking
    6.1.4 还是畅通工程
    6.1.3 畅通工程
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/11959351.html
Copyright © 2011-2022 走看看