目录

noip模拟8

T1

考场上想的是tarjan缩点,但是又忘了tarjan怎么打了。考完试发现tarjan也不是正解。所以tarjan:咕

正解是直接计算,统计自己连自己的和连别人的边数。如果边不联通就输出0

正解很短

CODE
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;

struct EDGE {
  int to, next;
} edge[maxn];
int tote, head[maxn];
void addEdge(int from, int to) {
  edge[++tote].next = head[from];
  edge[tote].to = to;
  head[from] = tote;
}
int m, n;
int visn;
bool vis[maxn];
void dfs(int id) {
  vis[id] = true;
  for (int i = head[id]; i; i = edge[i].next) {
    int to = edge[i].to;
    if (vis[to]) {
      visn++;
      continue;
    }
    dfs(to);
  }
}
int SC, CT, in[maxn];
int main() {
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int f, t;
    cin >> f >> t;
    if (t == f) {
      SC++;
      addEdge(f, t);
    } else {
      CT++;
      addEdge(f, t);
      addEdge(t, f);
      in[t]++;
      in[f]++;
    }
  }
  for (int i = 1; i <= n; i++) {
    dfs(i);
    if (visn != 0) break;
    vis[i] = 0;
  }
  for (int i = 1; i <= n; i++) {
    if (!vis[i] && head[i] != 0) {
      cout << 0 << endl;
      return 0;
    }
  }
  int ans = 0;
  ans += SC * (SC - 1) / 2;
  ans += SC * CT;
  for (int i = 1; i <= n; i++) {
    if (in[i] != 0) ans += in[i] * (in[i] - 1) / 2;
  
  }cout << ans << endl;
  return 0;
}
# T2

正解更短

注意 r-l 优化 否则会 TLE

彭师傅的解法LINK

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
#define int long long 
using namespace std;
const int maxn = 100010;

int n, k;
int a[maxn];
int C;
signed main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    k += a[i];
  }
  int ans = 0;
  int r = 0;
  for (int l = 1; l <= k; l = r + 1) {
    r = k / (k / l);
    int d = 0;
    for (int i = 1; i <= n; i++) {
      d += ceil(1.0 * a[i] / r);
    }
    if (d * r <= k) ans = r;
  }
  cout << ans << endl;
  return 0;
}

T3

还不会

T4

大水题不提,快读+printf就能AC 写假了的码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <bits/stdc++.h>
#define MOD 998244353

using namespace std;
const int maxn = 600010;

struct EDGE {
  int next, to;
} edge[maxn];
int tote, head[maxn];
void addEdge(int from, int to) {
  edge[++tote].to = to;
  edge[tote].next = head[from];
  head[from] = tote;
}
int size[maxn], father[maxn], dep[maxn], son[maxn], top[maxn], dfn[maxn],
    rk[maxn];
int cnt, root[maxn];

#ifdef __fread
inline char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int read() {
  char ch = nc();
  int sum = 0;
  while (!(ch >= '0' && ch <= '9')) ch = nc();
  while (ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = nc();
  return sum;
}
#endif
#ifndef __fread
inline int read() {
  int ans = 0, f = 1;
  char c = getchar();
  while (!isdigit(c)) {
    if (c == '-') f = -f;
    c = getchar();
  }
  while (isdigit(c)) {
    ans = (ans << 3) + (ans << 1) + (c ^ 48);
    c = getchar();
  }
  return ans * f;
}
#endif

int qpow(int base, int power, int mod) {
  int ans = 1;
  while (power) {
    if (power & 1) {
      ans = 1ll * ans * base % mod;
    }
    base = (1ll * base * base) % mod;
    power >>= 1;
  }
  return ans;
}
void dfs1(int id, int fa, int depth) {
  father[id] = fa;
  dep[id] = depth;
  size[id] = 1;
  for (int i = head[id]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (v == fa) continue;
    dfs1(v, id, depth + 1);
    size[id] += size[v];
    if (size[v] > size[son[id]]) son[id] = v;
  }
}
void dfs2(int id, int tp) {
  top[id] = tp;
  dfn[id] = ++cnt;
  rk[cnt] = id;
  if (!son[id]) return;
  dfs2(son[id], tp);
  for (int i = head[id]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (v != son[id] && v != father[id]) dfs2(v, v);
  }
}
int getLCA(int a, int b) {
  while (top[a] != top[b]) {
    if (dep[top[a]] > dep[top[b]]) {
      a = father[top[a]];
    } else {
      b = father[top[b]];
    }
  }
  if (dep[a] > dep[b]) {
    return b;
  } else {
    return a;
  }
}

int n, m;
int main() {
  n = read();
  for (int i = 1; i < n; i++) {
    int f, t;
    f = read();
    t = read();
    addEdge(f, t);
    addEdge(t, f);
  }
  dfs1(1, 1, 0);
  dfs2(1, 1);
  int m;
  cin >> m;
  for (int i = 1; i <= m; i++) {
    int x, y, k;
    x = read();
    y = read();
    k = read();
    int rtd = dep[getLCA(x, y)];
    int xpl = dep[x] - rtd;
    int ypl = dep[y] - rtd;
    long long ans = 0;
    while (xpl != 0) {
      ans += qpow(rtd + xpl, k, MOD);
      xpl--;
    }
    ans %= MOD;
    while (ypl != 0) {
      ans += qpow(rtd + ypl, k, MOD);
      ypl--;
    }
    ans %= MOD;
    ans += qpow(rtd, k, MOD);
    printf("%lld\n", ans % MOD);
  }
  return 0;
}