1. 程式人生 > >【BZOJ2253】[2010 Beijing wc]紙箱堆疊 CDQ分治

【BZOJ2253】[2010 Beijing wc]紙箱堆疊 CDQ分治

owb lld swap NPU highlight namespace arr equal light

Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 500060
#define ll long long 
#define nex (oo = (oo * A) % mod)
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,cnt,fin,ans[maxn]; 
long long mod,oo = 1,A,H[maxn]; 
void getmax(int &a,int b){ if(b>a) a = b; }
struct Node{
    long long  x,y,z; 
    int id; 
}node[maxn],arr[maxn]; 

int cmpx(Node a,Node b){ return(a.x==b.x&&a.y==b.y)? (a.z < b.z) : ((a.x==b.x)?a.y<b.y:a.x<b.x); }
int cmpy(Node a,Node b) {
    if(a.y==b.y)  return a.z<b.z;  
    return a.y<b.y; 
}
int equal(Node a,Node b) { return (a.x==b.x&&a.y==b.y&&a.z==b.z); }

struct BIT{
    int C[maxn];
    int lowbit(int x){ return x & (-x); }
    void update(int p,int x) { 
        while(p <  maxn) {
            C[p] = max(C[p],x);
            p += lowbit(p);
        } 
    }
    int query(int p) { 
        if(p<=0) return 0; 
        int ss=0;
        while(p>0) {
            ss=max(ss,C[p]),p-=lowbit(p); 
        }
        return ss; 
    }
    void del(int p) { 
        while(p < maxn) C[p] = 0,p+=lowbit(p); 
    }
}tree;
void solve(int l,int r){
    if(l >= r) return;
    int mid = (l + r) >> 1,tl = l,tr = mid+1; 
    solve(l,mid); 
    sort(arr + l,arr + mid + 1,cmpy),sort(arr + mid + 1,arr + r + 1,cmpy);  
    while(tl<=mid&&tr<=r) {
        if(arr[tl].y<arr[tr].y) {
            tree.update(arr[tl].z,ans[arr[tl].id]);             
            ++tl;
        }
        else {
            getmax(ans[arr[tr].id],tree.query(arr[tr].z-1)+1); 
            ++tr; 
        }
    }
    for(int i = tr;i<=r;++i) getmax(ans[arr[i].id],tree.query(arr[i].z-1)+1); 
    for(int i = l;i<=mid;++i) tree.del(arr[i].z); 
    sort(arr+mid+1,arr+1+r,cmpx),solve(mid+1,r); 
}
int main(){
    //setIO("input");
    scanf("%lld%lld%d",&A,&mod,&n);             
    for(int i = 1;i <= n; ++i){
        oo = (oo * A) % mod,node[i].x = oo; 
        oo = (oo * A) % mod,node[i].y = oo;
        oo = (oo * A) % mod,node[i].z = oo;
        if(node[i].x > node[i].y) swap(node[i].x,node[i].y);
        if(node[i].x > node[i].z) swap(node[i].x,node[i].z);
        if(node[i].y > node[i].z) swap(node[i].y,node[i].z); 
    } 
    node[0].x = node[0].y = node[0].z = -333333333; 
    sort(node + 1,node + 1 + n,cmpx); 
    for(int i = 1;i <= n; ++i) 
        if(!equal(node[i],node[i-1])) arr[++cnt] = node[i],arr[cnt].id = cnt; 
    //================================================================================= 
    //對 x 離散
    for(int i = 1;i <= cnt; ++i) H[i] = arr[i].x;
    sort(H+1,H+1+cnt);
    for(int i = 1;i <= cnt; ++i) arr[i].x = lower_bound(H + 1,H + 1 + cnt,arr[i].x)-H;
    //對 y 離散
    for(int i = 1;i <= cnt; ++i) H[i] = arr[i].y;
    sort(H+1,H+1+cnt);
    for(int i = 1;i <= cnt; ++i) arr[i].y = lower_bound(H + 1,H + 1 + cnt,arr[i].y)-H;
    //對 z 離散
    for(int i = 1;i <= cnt; ++i) H[i] = arr[i].z;
    sort(H + 1,H + 1 + cnt);
    for(int i = 1;i <= cnt; ++i) arr[i].z = lower_bound(H + 1,H + 1 + cnt,arr[i].z)-H; 
    //=================================================================================

    for(int i = 1;i <= cnt; ++i) ans[arr[i].id] = 1; 
    solve(1,cnt);

    for(int i = 1;i <= cnt; ++i) fin = max(fin,ans[arr[i].id]);
    printf("%d",fin); 
    return 0; 
}

  

【BZOJ2253】[2010 Beijing wc]紙箱堆疊 CDQ分治