三,四元环计数

  • 想证明的东西一定要尝试验证是不是对的,可以尝试卡
  • 证明
  • 定义优先级按\(deg\)比较, 相同比编号, 然后大往小连边
  • 对于任意的点\(u\), \(in_u \leq \sqrt m\)
  • 所以, 我们枚举\(u\)点, 再枚举他的下一个\(v \leq u\)点, 再枚举下一个\(w \leq v\)
  • 每一个点的贡献是$ in_u \times deg_u \leq m \sqrt m$

\(\Large Three\)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, deg[N], vis[N];
vector<int> g[N], e[N];
void adde(int u, int v){g[u].push_back(v), deg[v]++;}
void addt(int u, int v){e[u].push_back(v);}
int cmp(int x, int y){return deg[x] > deg[y] || (deg[x] == deg[y] && x > y);}
int main()
{
  scanf("%d%d", &n, &m);
  int u, v;
  for(int i = 1; i <= m; i++)
  {
    scanf("%d%d", &u, &v);
    adde(u, v), adde(v, u);
  }
  int ans = 0;
  for(int u = 1; u <= n; u++)
  {
    for(auto v : g[u]) if(cmp(u, v)) vis[v] = 1;
    for(auto v : g[u])
    {
      if(!cmp(u, v)) continue;
      for(auto w : g[v])
      {
        if(!cmp(v, w)) continue;
        if(vis[w]) ans++;
      }
    }
    for(auto v : g[u]) if(cmp(u, v)) vis[v] = 0;
  }
  printf("%d\n", ans);
  return 0;
}
  • \(\Large Four\)
#include<bits/stdc++.h>

#define forall(i, u, g, v) for(int i = 0, v; i < (int)g[u].size() && (v = g[u][i], 1); i++)
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int n, m, deg[N], cnt[N], a[N];
ll sum[N];
vector<int> g[N];
void adde(int u, int v){g[u].push_back(v), deg[v]++;}
int cmp(int x, int y){return deg[x] > deg[y] || (deg[x] == deg[y] && x > y);}
int main()
{
  // freopen("2.in", "r", stdin);
  scanf("%d%d", &n, &m);
  for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
  int u, v;
  for(int i = 1; i <= m; i++)
  {
    scanf("%d%d", &u, &v);
    adde(u, v), adde(v, u);
  }
  for(int u = 1; u <= n; u++)
  {
    forall(i, u, g, v)
    {
      if(!cmp(u, v)) continue;
      forall(j, v, g, w)
      {
        if(!cmp(u, w)) continue;
        sum[w] += cnt[w];
        sum[u] += cnt[w];
        cnt[w]++;
      }
    }
    forall(i, u, g, v)
    {
      if(!cmp(u, v)) continue;
      forall(j, v, g, w)
      {
        if(!cmp(u, w)) continue;
        sum[v] += (cnt[w] - 1);
      }
    }
    forall(i, u, g, v)
    {
      if(!cmp(u, v)) continue;
      forall(j, v, g, w)
      {
        if(!cmp(u, w)) continue;
        cnt[w]--;
      }
    }
  }
  int ans = 0;
  for(int i = 1; i <= n; i++)
  {
    a[i] %= mod;
    sum[i] %= mod;
    ans = (ans + a[i] * sum[i] % mod) % mod;
  }
  printf("%d\n", ans);
  return 0;
}
posted @ 2020-11-22 20:43  SegmentTree  阅读(24)  评论(0编辑  收藏  举报