• BZOJ 4264 小c找朋友


    传送门

    题目大意:

    给定一张无向图,求满足以下条件的点对 (x,y) 数目:对任意点 z (z!=x,y),边 (x,z) 和 (y,z) 同时存在或同时不存在。

    题目分析:

    首先要分析的出如果xy满足要求,那么x和y的连边点集应该是相同的,这里又分为两种情况:

    • xy之间有边,加上自己的hash值后求集合哈希值出现的次数
    • xy之间没有边,直接hash求不包含自己的集合哈希值出现的次数

    bzoj加上srand(time(0))就会RE,有毒

    code

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    namespace IO{
        inline int read(){
            int i = 0, f = 1; char ch = getchar();
            for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
            if(ch == '-') f = -1, ch = getchar();
            for(; ch >= '0' && ch <= '9'; ch = getchar()) i = (i << 3) + (i << 1) + (ch - '0');
            return i * f;
        }
        inline void wr(ll x){
            if(x < 0) putchar('-'), x = -x;
            if(x > 9) wr(x / 10);
            putchar(x % 10 + '0');
        }
    }using namespace IO;
    
    const int N = 1e6 + 5, M = 1e6 + 5;
    int n, m;
    typedef unsigned long long ull;
    
    const int Mod = 233333;
    ull val[N], sum[N];
    ll ans, degree[N];
    typedef pair<ull, ll> P;
    typedef pair<int, int> EP;
    vector<EP> edges;
    vector<P> hashMap[Mod + 5];
    
    inline void insert(ull x, ll c){
        int key = x % Mod;
        for(int i = 0; i < hashMap[key].size(); i++)
            if(hashMap[key][i].first == x) {hashMap[key][i].second+=c;return;}
        hashMap[key].push_back(P(x, c));
    }
    
    inline ll query(ull x){
        int key = x % Mod;
        for(int i = 0; i < hashMap[key].size(); i++)
            if(hashMap[key][i].first == x) return hashMap[key][i].second;
        return 0;
    }
    
    int main(){
        n = read(), m = read();
        for(int i = 1; i <= n; i++) val[i] = 1ull * rand() * rand() + rand() ;
        for(int i = 1; i <= m; i++){
            int x = read(), y = read(); edges.push_back(EP(x, y)); degree[x]++, degree[y]++;
            sum[x] += val[y], sum[y] += val[x];
        }
        
        for(int i = 1; i <= n; i++) insert(sum[i],1);
        for(int i = 1; i <= n; i++){
            ll x = query(sum[i]);  insert(sum[i], -x);
            ans += x * (x - 1) / 2;
        }
        for(int i = 0; i < edges.size(); i++){
            int x = edges[i].first, y = edges[i].second;
            if(degree[x] == degree[y] && sum[x] + val[x] == sum[y] + val[y]) ans++;
        }
        wr(ans), putchar('
    ');
        return 0;    
    } 
    
  • 相关阅读:
    迭代器、生成器
    函数(函数基础、装饰器、递归、匿名函数)
    文件处理
    python对象、引用
    字符编码
    流程控制if、while、for
    编程与编程语言
    Java源码阅读(五)—— AbstractQueuedSynchronizer
    Java并发编程(二) —— volatile
    Java源码阅读(七)—— ReentrantReadWriteLock
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7679483.html
Copyright © 2020-2023  润新知