102606C. Coronavirus Battle time limit per test4 seconds(三维拓扑序)

题:https://codeforces.com/gym/102606/problem/C

题意:给出n,k1,k2,然后题目给出n个点的转化,给出定义:在三维空间内,i 能保护 j 当且仅当 xi<=xj&&yi<=yj&&zi<=zj(且题目保证没有共点),每一轮没被保护的点都会消失,问每个点什么时候消失;

分析:采用cdq分治,求拓扑序

例如 第3个样例离散化后:

3 5 4
1 4 2
5 1 1
2 2 3
4 3 5

这5个点的拓扑序为1 0 0 0 1,虽说第4个和第2个都比第1个数小,但第4个和第2个数的拓扑序为0,(要区分以前写的cdq分治)

#include<bits/stdc++.h>
#define lowbit(i) i&(-i)
using  namespace std;
typedef unsigned long long ll;
const int M=2e5+5;
ll x[M],y[M],z[M];
int tree[M<<1],ans[M];
int n;
struct node{
    ll x,y,z;
    int id,ans,cnt;
    bool operator < (const node &b)const{
        if(x!=b.x)
            return x<b.x;
        else if(y!=b.y)
            return y<b.y;
        else
            return z<b.z;
    }
}a[M],temp[M];
void add(int pos,int val){
    while(pos<M)
        tree[pos]=max(tree[pos],val),pos+=lowbit(pos);
}
void del(int x){
    for(int i=x;i<M;i+=lowbit(i))
        tree[i]=0;
}
int query(int pos){
    int res=0;
    while(pos)
        res=max(res,tree[pos]),pos-=lowbit(pos);
    return res;
}
bool cmp1(node p,node q){
    return p.x<q.x;
}
bool cmp2(node p,node q){
    return p.id<q.id;
}
void cdq(int l,int r){
    int midd=(l+r)>>1;
    if(l==r)
        return;
    cdq(l,midd);
    sort(a+l,a+midd+1,[&](node A,node B){
         return A.y<B.y;
    });
    sort(a+midd+1,a+r+1,[&](node A,node B){
         return A.y<B.y;
    });
    int t1=l,t2=midd+1;
    for(int i=l;i<=r;i++){
        if((t1<=midd&a[t1].y<=a[t2].y)||t2>r){
            add(a[t1].z,ans[a[t1].id]);
            t1++;
        }
        else{
            ans[a[t2].id]=max(ans[a[t2].id],query(a[t2].z)+1);
            t2++;
        }
    }
    for(int i=l;i<=midd;i++)
        del(a[i].z);
    sort(a+midd+1,a+r+1,[&](node A,node B){
         return A.x<B.x;
    });
    cdq(midd+1,r);
}
void init(){
    sort(x+1,x+1+n);
    int m=unique(x+1,x+1+n)-x-1;
    for(int i=1;i<=n;i++)
        a[i].x=lower_bound(x+1,x+1+m,a[i].x)-x;
    sort(y+1,y+1+n);
    m=unique(y+1,y+1+n)-y-1;
    for(int i=1;i<=n;i++)
        a[i].y=lower_bound(y+1,y+1+m,a[i].y)-y;
    sort(z+1,z+1+n);
    m=unique(z+1,z+1+n)-z-1;
    for(int i=1;i<=n;i++)
        a[i].z=lower_bound(z+1,z+1+m,a[i].z)-z;
}
unsigned long long k1, k2;
unsigned long long CoronavirusBeats() {
    unsigned long long k3 = k1, k4 = k2;
    k1 = k4;
    k3 ^= k3 << 23;
    k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);
    return k2 + k4;
}
int main(){
    scanf("%d%llu%llu",&n,&k1,&k2);
    for(int i=1;i<=n;i++)
        ans[i]=1;
    for(int i=1;i<=n;i++){
        x[i] = CoronavirusBeats();
        y[i] = CoronavirusBeats();
        z[i] = CoronavirusBeats();
        a[i].x=x[i],a[i].y=y[i],a[i].z=z[i],a[i].cnt=1,a[i].id=i;
    }
    init();
    
    sort(a+1,a+1+n,[&](node A,node B){
         return A.x<B.x;
    });
    /*int now=0;
    for(int i=n-1;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)
            now++;
        else
            now=0;
        ans[a[i].id]+=now;
    }*/
    cdq(1,n);
    int maxx=0;
    for(int i=1;i<=n;i++){
        maxx=max(maxx,ans[i]);
        ans[i]--;
    }
    printf("%d\n",maxx);
    for(int i=1;i<=n;i++)
        printf("%d ",ans[i]);
    return 0;
}
View Code

 

posted @ 2020-05-27 12:03  starve_to_death  阅读(225)  评论(0编辑  收藏  举报