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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮

浙公网安备 33010602011771号