--- tags: IOICamp --- # Day5 模擬賽 :::spoiler Description ![](https://i.imgur.com/RepFDu5.png) ::: :::spoiler Problems (PDF) QQ {%pdf https://www.csie.ntu.edu.tw/~b07902024/ioicamp2020-final.pdf %} ::: :::spoiler Scoreboard (155min) ![](https://i.imgur.com/qjOefCc.png) ::: :::spoiler Scoreboard (165min, pM rejudged) ![](https://i.imgur.com/NWW6iq3.png) ::: :::spoiler Scoreboard (220min) ![](https://i.imgur.com/0GvbuxS.png) ::: :::spoiler Scoreboard (240min, Frozen) ![](https://i.imgur.com/x3Ulb6V.png) ::: :::spoiler Scoreboard (317min, Ended, Frozen) ![](https://i.imgur.com/c6lDwA2.png) ::: --- [TOC] #### **pA. 二分圖判定** :::spoiler Solution (SorahISA) ```cpp= #pragma GCC optimize("Ofast", "unroll-loops") #include <bits/stdc++.h> using namespace std; using lli = long long; const int maxn = 1E3; vector<int> adj[maxn]; bool side[maxn][maxn], flag = 1; int col[maxn] = {}; void dfs(int now) { for (auto x : adj[now]) { if (col[x] == 0) { col[x] = col[now] ^ 1; dfs(x); } else if (col[x] == col[now]) { flag = 0; } } } int main() { lli n, m; scanf("%lld %lld", &n, &m); int u, v; if (n > maxn) { printf("No\n"); return 0; } for (int i = 0; i < m; ++i) { scanf("%d %d", &u, &v); side[u][v] = 1; side[v][u] = 1; } for (int i = 1; i <= n; ++i) { for (int j = i+1; j <= n; ++j) { if (!side[i][j]) { adj[i].push_back(j); adj[j].push_back(i); } } } for (int i = 1; i <= n; ++i) { if (!col[i]) { col[i] = 2; dfs(i); } } if (flag) printf("Yes\n"); else printf("No\n"); return 0; } ``` ::: #### **pB. 當堅果遇上松果** #### **pC. 當堅果遇上隨機** #### **pD. 小風數堅果** #### **pE. 最好吃的堅果** #### **pF. 小風愛數堅果樹** #### **pG. 當堅果遇上午餐** :::spoiler Solution (SorahISA) ```cpp= #include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, m; cin >> n >> m; int kind[n], cost[m]; for (int i = 0; i < n; ++i) cin >> kind[i]; for (int i = 0; i < m; ++i) cin >> cost[i]; string s, t; cin >> s >> t; int ans = 0; for (int i = 0; i < n; ++i) { if (s[i] == '0') { ans += cost[kind[i] - 1]; ans -= t[i] == '1'; } } cout << ans << "\n"; return 0; } ``` ::: #### **pH. 照亮堅果樹** #### **pI. 周伯欲點兵,姬桂算剩餘** :::spoiler Solution (loIicon) ```cpp= /* ?__,.??.    / ,?﹑ 〉      \ ', !-─?-i / /’       /‘?'    L//‘?﹑      /  /,  /|  ,  ,    ',    ?  / /-?/ i L_ ? ?!  i     ? ? 7?‘?  ?'?-?﹑!?|  |      !,/7 '0'   ’0i?|   |         |.?"  _   ,,,, / |./   |      ?'| i>.﹑,,__ _,.? /  .i  |       ?'| | / k_7_/?'?, ?. |        | |/i 〈|/  i ,.? | i |       .|/ / i:   ?!  \ |         k?>﹑?   _,.?﹑   /﹑!        !'〈//‘T’', \ ‘'7'?r'        ?'?L__|___i,___,??|?          ?-,/ |___./          '?'  !_,.: ub33 love loli<3 */ #include <iostream> #include <algorithm> #define loli long long #define iris 1000000007 using namespace std; int arr[100010],n; struct st{ int ouo[266666]; bool tag[266666]; void build(int l,int r,int i,int o) { int m=(l+r)>>1; if(l==r) ouo[i]=(arr[l]>>o)&1; else { build(l,m,i*2,o); build(m+1,r,i*2+1,o); ouo[i]=ouo[i*2]+ouo[i*2+1]; } } inline void push(int l,int r,int i) { int m=(l+r)/2; if(!tag[i]) return; tag[i]=0; if(l!=r) { tag[i*2]^=1; tag[i*2+1]^=1; ouo[i*2]=m-l+1-ouo[i*2]; ouo[i*2+1]=r-m-ouo[i*2+1]; ouo[i]=ouo[i*2]+ouo[i*2+1]; } } void rev(int l,int r,int a,int b,int i) { int m=(l+r)>>1; push(l,r,i); if(a<=l && r<=b) { ouo[i]=r-l+1-ouo[i]; tag[i]^=1; return; } else if(b<=m) { rev(l,m,a,b,i*2); } else if(a>m) { rev(m+1,r,a,b,i*2+1); } else { rev(l,m,a,b,i*2); rev(m+1,r,a,b,i*2+1); } ouo[i]=ouo[i*2]+ouo[i*2+1]; } int qry(int l,int r,int a,int b,int i) { int m=(l+r)>>1; push(l,r,i); if(a<=l && r<=b) return ouo[i]; else if(b<=m) return qry(l,m,a,b,i*2); else if(a>m) return qry(m+1,r,a,b,i*2+1); else return qry(l,m,a,b,i*2)+qry(m+1,r,a,b,i*2+1); } }aoi[31]; inline loli query(int l,int r) { loli i,res=0; for(i=0;i<31;i++) { res+=(loli)aoi[i].qry(1,n,l,r,1)<<i; } return (res)/2-(r-l+1)+(aoi[0].qry(1,n,l,r,1)+1)/2; } inline void change(int l,int r,int k) { int i; for(i=0;i<31;i++) { if((k>>i)&1) { aoi[i].rev(1,n,l,r,1); } } } signed main(){ ios::sync_with_stdio(0); cin.tie(0); int q,i,x,a,b,c; cin>>n>>q; for(i=1;i<=n;i++) { cin>>arr[i]; } for(i=0;i<31;i++) { aoi[i].build(1,n,1,i); } while(q--) { cin>>x; if(x==1) { cin>>a>>b; cout<<query(a,b)<<'\n'; } else { cin>>a>>b>>c; change(a,b,c); } } return 0; } ``` ::: #### **pJ. 堅果巧克力** :::spoiler Solution (SorahISA, Brute-Force) ```cpp= #pragma GCC optimize("Ofast", "unroll-loops") #include <bits/stdc++.h> using namespace std; using lli = long long; int n, w, h, a[20], t[20], fl = 0, tok = 0; stack<int> ans, tmp; void dfs(int W, int H, int Pick) { if (fl) return; if (Pick == 0) { fl = 1; while (!ans.empty()) { tmp.push(ans.top()); ans.pop(); } return; } for (int i = 0; i < n; ++i) { if (Pick & (1 << i) and a[i] % W == 0) { ans.push(t[i]); ans.push(W); ans.push(a[i] / W); dfs(W, H - a[i] / W, Pick ^ (1 << i)); if (!ans.empty()) {ans.pop(); ans.pop(); ans.pop();} } if (Pick & (1 << i) and a[i] % H == 0) { ans.push(t[i]); ans.push(a[i] / H); ans.push(H); dfs(W - a[i] / H, H, Pick ^ (1 << i)); if (!ans.empty()) {ans.pop(); ans.pop(); ans.pop();} } } } int main() { srand(time(NULL)); scanf("%d %d %d", &n, &w, &h); for (int i = 0; i < n; ++i) scanf("%d", &a[i]); for (int i = 0; i < n; ++i) t[i] = i + 1; for (int i = 1; i < n; ++i) { int rnd = rand() % i; swap(a[i], a[rnd]); swap(t[i], t[rnd]); } dfs(w, h, (1 << n) - 1); if (fl) { puts("Yes"); while (!tmp.empty()) { printf("%d", tmp.top()); tmp.pop(); printf("%c", ++tok % 3 == 0 ? '\n' : ' '); } } else { puts("No"); } return 0; } ``` ::: #### **pK. 天天吃堅果** #### **pL. 小風的堅果塔** :::spoiler Solution (SorahISA) ```cpp= #pragma GCC optimize("Ofast", "unroll-loops") #include <cstdio> #include <utility> #include <algorithm> using namespace std; using lli = long long; #define A first #define W second const int maxn = 5E3 + 5; pair<lli, lli> nut[maxn]; lli dp[maxn][maxn], ans = 0; int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%lld %lld", &nut[i].A, &nut[i].W); sort(nut, nut + n); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { dp[i][j] = 0; } dp[i][0] = nut[i].W; if (i) dp[i][0] += nut[0].W; // Max[i][0] = dp[i][0]; } for (int i = 2; i < n; ++i) { for (int j = 1; j < i; ++j) { /// dp[i][j] = max_{w[k] <= w[i] - w[j]}(dp[j][k]) + w[i] /// int lo = 0, hi = j, mi; /// binary search lower_bound of allowed range [0, lo) /// while (lo < hi) { mi = (lo + hi) >> 1; if (nut[i].A - nut[j].A < nut[mi].A) hi = mi; else lo = mi + 1; } if (lo == 0) { dp[i][j] = nut[i].W + nut[j].W; // Max[i][j] = max(Max[i][j - 1], dp[i][j]); dp[i][j] = max(dp[i][j - 1], dp[i][j]); ans = max(ans, dp[i][j]); continue; } /// find max_{0 <= k < lo}(dp[j][k]) /// // dp[i][j] = Max[j][lo - 1] + nut[i].W; dp[i][j] = dp[j][lo - 1] + nut[i].W; /// update max and answer /// // Max[i][j] = max(Max[i][j - 1], dp[i][j]); dp[i][j] = max(dp[i][j - 1], dp[i][j]); ans = max(ans, dp[i][j]); // /// O(n^3) solution /// // for (int k = 0; k < j; ++k) { // if (nut[i].A - nut[j].A < nut[k].A) break; // dp2[i][j] = max(dp2[i][j], dp2[j][k]); // } // dp2[i][j] += nut[i].W; // ans2 = max(ans2, dp2[i][j]); } } printf("%lld\n", ans); return 0; } ``` ::: #### **pM. 乘法大師** :::spoiler Solution (SorahISA) ```cpp= #include <bits/stdc++.h> using namespace std; using lli = long long; lli part[50]; //void dfs(int now, int left, int num) { // if (left == 0) { // ++part[num]; // } // // for (int i = now; i <= left; ++i) { // if (i == left or left - i >= i) { // dfs(i, left - i, num); // } // } //} void check() { // part[1] = 1; // for (int i = 2; i <= 30; ++i) { // part[i] = part[i - 1]; // dfs(2, i, i); // printf("part[%2d] = %lld;\n", i, part[i]); // } part[ 1] = 1; part[ 2] = 2; part[ 3] = 3; part[ 4] = 5; part[ 5] = 7; part[ 6] = 11; part[ 7] = 15; part[ 8] = 22; part[ 9] = 30; part[10] = 42; part[11] = 56; part[12] = 77; part[13] = 101; part[14] = 135; part[15] = 176; part[16] = 231; part[17] = 297; part[18] = 385; part[19] = 490; part[20] = 627; part[21] = 792; part[22] = 1002; part[23] = 1255; part[24] = 1575; part[25] = 1958; part[26] = 2436; part[27] = 3010; part[28] = 3718; part[29] = 4565; part[30] = 5604; } int main() { check(); int n; scanf("%d", &n); if (n == 1) { printf("0\n"); return 0; } int arr[30] = {}, tok = 0; for (int i = 2; i*i <= n; ++i) { if (n / i * i == n) ++tok; while (n / i * i == n) { n /= i; ++arr[tok]; } } assert(tok <= 30); // if (n != 1) { // arr[++tok] = 1; // } lli ans = 1; for (int i = 1; i <= tok; ++i) { ans *= part[arr[i]]; } printf("%lld\n", ans); return 0; } ``` :::