第八場比賽 題解 = >敗者死於絕望,勝者死於渴望 # [z071](https://judge.cp.ccns.io/problem/z071): 直覺是建表,但範圍 $3⋅10^9$ 在要記憶體時就會 RE 了 而 $O(\sqrt N)$ 的**試除法**又太慢 所以就有以下的作法: ```cpp #include<bits/stdc++.h> using namespace std; typedef long long Int; int const maxn = 55e3; Int N; bool is_p[maxn]; vector<int> prime; int main() { // sieve fill(is_p, is_p+maxn, true); is_p[1] = false; for(int n = 2; n < maxn; n++) { if(is_p[n]) prime.push_back(n); for(int p: prime) { if(n*p >= maxn) break; is_p[n*p] = false; if(n%p == 0) break; } } // check while(~scanf("%lld", &N)) { bool ok = N != 1; for(Int p: prime) { if(p*p > N) break; if(N%p == 0) { ok = false; break; } } puts(ok? "YES" : "NO"); } return 0; } ``` 或是用 [Miller-Rabin **測試**法](https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test)也行, 傳說有幾個 liar 可以涵蓋 64-bit 整數,一直試錯的那幾隊可以去查一下 XD # [z072](https://judge.cp.ccns.io/problem/z072): Sort 簡單題目。 注意 Long Long Int ```cpp #include <bits/stdc++.h> #define ll long long using namespace std; ll n, m; vector< ll > a; vector< ll > s; vector< ll > ans; int main() { cin >> n >> m; a.resize(n); s.resize(n); ans.resize(m); for(int i = 0; i < n; i++) cin >> a[i]; for(int i = 0; i < n; i++) s[i] = (i == 0?0:s[i-1]) + a[i]; for(int i = 0; i < m; i++) { int x, y; cin >> x >> y; ans[i] = s[y-1] - (x == 1? 0 :s[x-2]); } sort(ans.begin(), ans.end()); ll cnt = 0; for(int i = 0 ; i < m; i++) cnt += ans[i] * (i+1); cout << cnt << endl; return 0; } ``` # [z073](https://judge.cp.ccns.io/problem/z073): 令 $K_i = 1234567891011\text{..}i$ ($i \le N$) 若 $a \equiv K_{i-1} \mod 2019$ > 其中等號**左項**為右項除以 $2019$ 的餘數 則 $$ a\cdot 10^{\text{len}(i)} \equiv K_{i-1}\cdot 10^{\text{len}(i)} \mod 2019 $$ > $\text{len}(x)$ 表示 $x$ 的位數 及 $$ \begin{split} a\cdot 10^{\text{len}(i)} + i &\equiv K_{i-1}\cdot 10^{\text{len}(i)} + i \mod 2019 \\ &\equiv K_{i}\mod 2019 \end{split} $$ 根據上述,迭代 $i$ 至 $N$ 就能算出 $K_N \text{ mod } 2019$ 了: ```python from math import log10 n = int(input()) a = 0 for i in range(1, n+1): a = (a * 10**(int(log10(i))+1) + i) % 2019 print(a) ``` # [z074](https://judge.cp.ccns.io/problem/z074): 想要考圖論,不解釋。 練習重建圖,計算degree。 ```cpp #include <bits/stdc++.h> #define pii pair<int, int> #define ff first #define ss second using namespace std; int n, m, q; vector<int> deg; priority_queue< pair<int, pii> > edge; vector< pii > data; vector<int> bs;//boss int fboss(int x) { if(x == bs[x]) return x; return bs[x] = fboss(bs[x]); } int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> q; bs.resize(n+1); for(int i = 1; i <= n; i++) bs[i] = i; deg.resize(n+1); data.resize(m); for(int i = 0; i < m; i++) { int a, b; cin >> a >> b; deg[a]++, deg[b]++; data[i].ff = a; data[i].ss = b; } for(int i = 0; i < m; i++) { int a = data[i].ff; int b = data[i].ss; int deg_min = min(deg[a], deg[b]); edge.push(make_pair(deg_min, data[i])); } vector<int> ans; ans.resize(n); int cnt = n; for(int i = n-1; i >= 0; i--) { //rebuild while(!edge.empty() && edge.top().ff > i) { pii now = edge.top().ss; edge.pop(); int bs_a = fboss(now.ff); int bs_b = fboss(now.ss); if(bs_a != bs_b) cnt--, bs[bs_a] = bs_b; } ans[i] = cnt-1; } for(int i = 0; i < q; i++) { int qq; cin >> qq; cout << ans[qq] << endl; } return 0; } ``` # [z075](https://judge.cp.ccns.io/problem/z075):