CF1260D A Game with Traps

http://codeforces.com/problemset/problem/1260/D
First, it is clear that you can think of half the answer, to row a sequence capability of an array of values like.
Consider how check.
The current value is provided two w, i.e. weights can not directly cross> w trap.
All traps are arranged in ascending order l. Can be found, if two or more
traps overlap, certainly the man from a minimum of a few pitfalls l went directly to
the largest r the best.
prove? Here is the case where only two intervals overlap.
Suppose two sections are [a, b], [c , d], a <c <b <d.
From a team trying to the d, a first total time is 3 (da); if A-> C
-> A-> B-> D-> the C-> d, total time is 3 (ca ) +3 (DB) - (CB)
= + 3D-2B-2C. 3A>. 3A-3D.
Double hand analog like.

#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;
}

Guess you like

Origin www.cnblogs.com/Purple-wzy/p/11959351.html