返回顶部

2021牛客暑期多校训练营3 J.Counting Triangles (思维)


  • 题意:有一张\(n\)个点的完全图,每条边为黑色或者白色,问你最多有多少三条边都是同色的三角形.

  • 题解:比赛时没想到,队友写的.8000个点,正面硬写的话只有\(O(n^3)\)这种暴力方法,肯定不行.不妨反着来看,考虑有多少不合法的三角形,不合法的三角形一定有两条同色边和一条异色边,这样的话我们在找不合法三角形的时候就算两次,最后减去的时候除2即可.

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    namespace GenHelper
    {
        unsigned z1,z2,z3,z4,b,u;
        unsigned get()
        {
            b=((z1<<6)^z1)>>13;
            z1=((z1&4294967294U)<<18)^b;
            b=((z2<<2)^z2)>>27;
            z2=((z2&4294967288U)<<2)^b;
            b=((z3<<13)^z3)>>21;
            z3=((z3&4294967280U)<<7)^b;
            b=((z4<<3)^z4)>>12;
            z4=((z4&4294967168U)<<13)^b;
            return (z1^z2^z3^z4);
        }
        bool read() {
          while (!u) u = get();
          bool res = u & 1;
          u >>= 1; return res;
        }
        void srand(int x)
        {
            z1=x;
            z2=(~x)^0x233333333U;
            z3=x^0x1234598766U;
            z4=(~x)+51;
            u = 0;
        }
    }
    using namespace GenHelper;
    bool edge[8005][8005];
    int main() {
      ll n;
      int seed;
      cin >> n >> seed;
      srand(seed);
      for (int i = 0; i < n; i++)
            for (int j = i + 1; j < n; j++)
                edge[j][i] = edge[i][j] = read();
    
      ll ans=n*(n-1)*(n-2)/6;
      ll res=0;
      for(int i=0;i<n;++i){
        ll cntw=0,cntb=0;
        for(int j=0;j<n;++j){
            if(i==j) continue;
            if(edge[i][j]==0){
                res+=cntw;
                cntb++;
            }
            else{
                res+=cntb;
                cntw++;
            }
        }
      }
      cout<<ans-res/2<<'\n';
        return 0;
    }
    
posted @ 2021-07-25 17:11  _Kolibri  阅读(91)  评论(0)    收藏  举报