BZOJ4610——[Wf2016]Ceiling Functi

水题一道,不是很懂为啥没人做。。。

1、题意:纠正一下。。bzoj的题意不是很对。。。注意不是堆,是不平衡的二叉树,就是非旋转的treap,

  另外。。。插入的时候,小于插在左边。。大于等于插在右边

2、分析:大概是wf签到题吧。。维护size,暴力的递归比较时候相同。。。。

<pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
#define M 10000
 
inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    } 
    while('0' <= ch && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
 
struct Node{
    int size, x;
    Node *ls, *rs;
} pos[M];
Node *root[M];
int tot;
int fa[M];
 
inline void insert(Node* &o, int x){
    if(o == NULL){
        o = &pos[++ tot];
        o -> size = 1;
        o -> x = x; 
        return;
    }
    o -> size ++;
    if(x < o -> x) insert(o -> ls, x);
    else insert(o -> rs, x);
} 
 
inline int find(int x){
    return fa[x] == x ? x : fa[x] = find(fa[x]);
}
 
inline bool diff(Node *x, Node *y){
    if(x == NULL && y == NULL) return 0;
    if(x == NULL) return 1;
    if(y == NULL) return 1;
    if(x -> size != y -> size) return 1;
    return diff(x -> ls, y -> ls) | diff(x -> rs, y -> rs);
}
 
int main(){
    int n = read(), K = read();
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= K; j ++){
            int x = read();
            insert(root[i], x);
        }
        fa[i] = i;
    }
    for(int i = 1; i <= n; i ++){
        for(int j = i + 1; j <= n; j ++){
            if(!diff(root[i], root[j])){
                int x = find(i), y = find(j);
                if(x != y){
                    fa[x] = y;
                }
            }
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i ++) if(find(i) == i){
        ans ++;
    }
    printf("%d\n", ans);
    return 0;
} 


 
 

你可能感兴趣的:(ceiling,乱搞,bzoj,functi,4610,Wf2016)