【Hash】【二分查找】17.6.3 集合 题解

来源:互联网 发布:淘宝自动纸箱封箱机 编辑:程序博客网 时间:2024/06/02 19:28

这里写图片描述
这里写图片描述

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <map>#include <vector>#define INF 92233720368546LL#define LL long longusing namespace std;const int maxx = 1e5 + 10, mod = 2e5;int n, k, num = 0;LL a[maxx];map<LL, int> G;struct Node {    int kill, cnt;    LL pos[2];    LL ber;    Node() { kill = cnt = ber = 0; }    bool operator < ( const Node &a ) const { return kill < a.kill; }} b[maxx];struct Ha {    vector<LL> ha[mod+10];    void Insert(LL x) {        int pos = x%mod;        for(int i = 0; i < ha[pos].size(); i++)            if(ha[pos][i] == x) return;        ha[pos].push_back(x);    }    int Find(LL x) {        int pos = x%mod;        for(int i = 0; i < ha[pos].size(); i++) if(ha[pos][i] == x) return 1;        return 0;    }} L;template <class T> inline void read(T &x) {    int flag = 1; x = 0;    char ch = getchar();    while(ch <  '0' || ch >  '9') { if(ch == '-')  flag = -1; ch = getchar(); }    while(ch >= '0' && ch <= '9') { x = (x<<1)+(x<<3)+ch-'0'; ch = getchar(); }    x *= flag;}inline void Unit() {    int col = a[1];    b[++num].cnt++;    b[num].ber = col;    for(int i = 2; i <= n; i++) {        if(col != a[i]) col = a[i], b[++num].ber = col;        b[num].cnt++;    }}int Binary_Find(LL x, int lft, int rgt, int Master) {    int mid = (lft+rgt)>>1;    if(lft == rgt) {        if(b[lft].ber != x) return 0;        b[Master].pos[b[Master].pos[0] ? 1 : 0] = b[lft].ber;        return b[lft].cnt;    }    if(b[mid].ber == x) {        b[Master].pos[b[Master].pos[0] ? 1 : 0] = b[mid].ber;        return b[mid].cnt;    }    return (x > b[mid].ber ? Binary_Find(x, mid+1, rgt, Master) : Binary_Find(x, lft, mid, Master));}inline void Static() {    for(int i = 1; i <= num; i++) {        if(!(b[i].ber%k)) b[i].kill += Binary_Find(b[i].ber/k, 1, num, i);        if(b[i].ber < INF) b[i].kill += Binary_Find(b[i].ber*k, 1, num, i);    }}inline int Select() {    int ans = 0;    sort(b+1, b+num+1);    for(int i = 1; i <= num; i++)        if(!L.Find(b[i].ber)) {            L.Insert(b[i].pos[0]);            L.Insert(b[i].pos[1]);            ans += b[i].cnt;;        }    return ans;}int main() {    freopen("set.in","r",stdin);    freopen("set.out","w",stdout);    read(n); read(k);    for(int i = 1, x; i <= n; i++) read(a[i]);    sort(a+1, a+n+1);    Unit();    Static();    printf("%d",Select());    return 0;}
原创粉丝点击