南昌不翻车 Codeforces Global Round 5

T神的场。

C2  :https://codeforces.com/contest/1237/problem/C2

题目大意: n个点,每次去掉一对点,保证围成的区域不能包含其他的点,输出方案。

题目思路:

        其实并没有想到C1的n方做法,直接做的C2,先按照x再按照y再按照z排序,如果两个点重合了,一定要先拿掉这些,如果两个点在一条纵轴线上,要优先拿这些,拿完之后,如果在一个面上,要优先拿这些,然后剩下的从后往前拿就行了。

#include
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
struct node
{
    int x,y,z,id;
}a[MAXN];
bool cmp(node a,node b)
{
    if(a.x == b.x){
        if(a.y == b.y){
            return a.zv,v1,v2;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i].x>>a[i].y>>a[i].z;
        a[i].id = i;
    }
    sort(a+1,a+1+n,cmp);
    a[0].x = 999999,a[0].y = -1;
    for(int i=n;i>=1;i--){
        if(a[i].x == a[i-1].x && a[i].y == a[i-1].y && a[i].z == a[i-1].z){
            cout<=0;i--){
        if(i!=0 && v[i].x == v[i-1].x && v[i].y == v[i-1].y){
            cout<=0;i--){
        if(i!=0 && v1[i].x == v1[i-1].x){
            cout<=0;i-=2){
        cout<

D:

 https://codeforces.com/contest/1237/problem/D

题目大意: 

       n个数字,一个音乐演奏开始的话,直到后边碰到一个比当前碰到最大值小一半的数字会停止,问以每一个开始的话,哪个停止。

题目思路:

       每一个都往后找一个第一个比他大的,在找一个第一个比他小一半的,如果先碰到比他大的,那么就可以从那个值转移过来,如果先碰到小的那个,就断了。

        可以线段树上维护一个区间最小值,二分以下得到后者,用单调栈得到前者。

#include
#define ll long long
using namespace std;
const int MAXN = 1e5+5;
int a[2*MAXN];
int Min[8*2*MAXN],n;
void build(int p,int l,int r)
{
    if(l==r){
        Min[p] = a[l];
        return ;
    }
    int mid = (l+r)/2;
    build(2*p,l,mid);
    build(2*p+1,mid+1,r);
    Min[p] = min(Min[2*p],Min[2*p+1]);
}
int ask(int p,int l,int r,int L,int R)
{
    if(L<=l&&r<=R){
        return Min[p];
    }
    int mid = (l+r)/2;
    int Minn = 0x7fffffff;
    if(L<=mid) Minn = min(Minn,ask(2*p,l,mid,L,R));
    if(R>mid) Minn = min(Minn,ask(2*p+1,mid+1,r,L,R));
    return Minn;
}
int r[2*MAXN],ss[2*MAXN];
struct node
{
    int id,val;
} b[2*MAXN],st[2*MAXN];
bool cmp(node a,node b)
{
    return a.val > b.val;
}
bool check(int x,int idx,int cc)
{
    if(ask(1,1,2*n,idx+1,idx+x) <= cc){
        return 1;
    }
    else return 0;
}
int ans[2*MAXN];
int ma,mi;
int main()
{
    cin>>n;
    mi = 0x7fffffff;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ma = max(ma,a[i]);
        mi = min(mi,a[i]);
        b[i].id = i;
        a[n+i] = a[i];
        b[i].val = a[i];
        b[n+i].val = a[i];
        b[n+i].id = n+i;
    }
    b[2*n+1].id = 2*n+1;
    b[2*n+1].val = 0x7fffffff;
    //cout<= 1 && b[i].val>st[tot].val){
            r[st[tot].id] = i;
            tot--;
        }
        st[++tot] = b[i];
    }
    sort(b+1,b+1+n,cmp);
    for(int i=1;i<=n;i++){
        int idx = b[i].id;
        int now = (a[idx]-1)/2;
        int _l = 1,_r = n-1,anss = -1;
        while(_l<=_r){
            int mid = (_l+_r)/2;
            if(check(mid,idx,now)){
                _r = mid-1;
                anss = mid;
            }
            else{
                _l = mid+1;
            }
        }
        if(anss == -1){
            ss[idx] = 0x7fffffff;
        }
        else ss[idx] = idx+anss;
    }
    for(int i=1;i<=n;i++){
        int idx = b[i].id;
        int big = r[idx],sm = ss[idx];
        if(big < sm){
            ans[idx] = ans[big] + big - idx;
            ans[n+idx] = ans[idx];
        }
        else{
            ans[idx] = sm-idx;
            ans[idx+n] = ans[idx];
        }
       // cout<

 

你可能感兴趣的:(codeforces)