天坑。。。
杭电
dls代码:https://ideone.com/Wo55gi
官方题解:http://bestcoder.hdu.edu.cn/blog/
2018 Multi-University Training Contest 1
1001 Maximum Multiple
打表找规律,发现只有当n是3倍数或者4倍数时才有解
而且当n%3 == 0,max(x*y*z) = (n/3) * (n/3) * (n/3) = n^3 / 27,
当n%4 == 0, max(x*y*z) = (n/2) * (n/4) * (n/4) = n^3 / 32。
正解是解不定方程组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); if(n % 3 == 0) printf("%lld ", 1LL * n * n * n / 27); else if(n % 4 == 0)printf("%lld ", 1LL * n * n * n / 32); else printf("-1 "); } return 0; }
1002 Balanced Sequence
思路:贪心,先把每个括号序列用栈来使得中间的都括号都匹配,使得右括号都在左边,左括号都在右边
然后排序,我们先把右括号小于等于左括号的排在前面,然后对于右括号小于等于左括号的情况,我们按
右括号从小到大排序(因为最左边的右括号都是被浪费掉的,浪费的越小越好),然后把右括号大于左括
号的情况排在后面,对于后面这种情况,我们按左括号从大到小排序(因为最右边的左括号都是被浪费掉
的,浪费的越小越好)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; struct node { int l, r; bool operator < (const node &t) const { if(r <= l && t.r > t.l) return true; if(r > l && t.r <= t.l) return false; if(r <= l && t.r <= t.l) return r < t.r; if(r > l && t.r > t.l) return l > t.l; } }a[N]; char s[N]; int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); int ans = 0; for (int i = 0; i < n; i++) { scanf("%s", s); int l = 0, r = 0; for (int j = 0; j < strlen(s); j++) { if(s[j] == '(') l++; else { if(l) l--, ans += 2; else r++; } } a[i].l = l; a[i].r = r; } sort(a, a+n); int now = a[0].l; for (int i = 1; i < n; i++) { if(a[i].r >= now) { ans += now*2; now = 0; } else { ans += a[i].r*2; now -= a[i].r; } now += a[i].l; } printf("%d ", ans); } return 0; }
1003 Triangle Partition
1004 Distinct Values
1005 Maximum Weighted Matching
1006 Period Sequence
1007 Chiaki Sequence Revisited
思路:打表找规律,发现每个数i出现了lowbit(i)的长度次,然后二分最后a[n]的值,复杂度nlog(n)*log(n),会TLE,然后发现,a[n] -> n/2,所以将二分区间改为[n/2, n/2+100]降低复杂度
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 1e9 + 7; const int inv = 5e8 + 4; LL cal(LL m) { LL ans = 0; for (int i = 0; i <= 60; i++) { LL cnt = m / (1LL << i); if(cnt == 0) break; ans += cnt; } return ans; } LL sum(LL m) { LL ans = 0; for (int i = 0; i <= 60; i++) { LL tot = 1LL << i; LL cnt = m / tot; if(cnt == 0) break; LL t = ((cnt % MOD * ((cnt + 1) % MOD)) % MOD * inv) % MOD; t = (t * (tot % MOD) % MOD) % MOD; ans = (ans + t) % MOD; } return ans; } int main() { int T; LL n; scanf("%d", &T); while(T--) { scanf("%lld", &n); if(n <= 2) { printf("%lld ", n); continue; } n--; LL l = n/2, r = (n/2)+100, m = (l + r) >> 1; while(l < r) { if(cal(m) >= n) r = m; else l = m + 1; m = (l + r) >> 1; } LL tot = cal(m-1); LL res = n - tot; LL ans = (res % MOD * (m % MOD)) % MOD; ans = (ans + sum(m-1) + 1) % MOD; ans = (ans + MOD) % MOD; printf("%lld ", ans); } return 0; }
1008 RMQ Similar Sequence
1009 Lyndon Substring
1010 Turn Off The Light
1011 Time Zone
2018 Multi-University Training Contest 2
1001 Absolute
1003 Cover
思路:将度数为奇数的点两两相连,然后跑欧拉图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<pii>g[N]; bool nodevs[N], edgevs[2*N]; int deg[N], cnt = 0, t, st; vector<int>vc, vcc; vector<int>ans[N]; void dfs(int u) { nodevs[u] = true; if(deg[u]&1) vc.pb(u), st = u; cnt++; for (int i = 0; i < g[u].size(); i++) { if(!nodevs[g[u][i].fi]) { dfs(g[u][i].fi); } } } void add() { for (int i = 0; i < vc.size(); i += 2) { g[vc[i]].pb({vc[i+1], t}); g[vc[i+1]].pb({vc[i], t}); t++; } } void DFS(int u) { for (int i = 0; i < g[u].size(); i++) { if(!edgevs[abs(g[u][i].se)]) { edgevs[abs(g[u][i].se)] = true; DFS(g[u][i].fi); vcc.pb(g[u][i].se); } } } void debug() { for (int i = 0; i < vcc.size(); i++) cout << vcc[i] << " "; cout << endl; } int main() { int n, m, u, v; while(~scanf("%d%d", &n, &m)) { mem(nodevs, false); mem(edgevs, false); mem(deg, 0); for (int i = 0; i <= n; i++) g[i].clear(); for (int i = 1; i <= m; i++) { ans[i].clear(); scanf("%d%d", &u, &v); g[u].pb({v, -i}); g[v].pb({u, i}); deg[u]++; deg[v]++; } int tot = 0; t = m+1; for (int i = 1; i <= n; i++) { if(!nodevs[i]) { cnt = 0; st = i; vc.clear(); dfs(i); if(cnt == 1) continue; add(); vcc.clear(); DFS(st); //debug(); int s = 0, sz = vcc.size(); if(vc.size() > 1) { while(abs(vcc[s]) <= m) { s++; } } else tot++; for (int i = s; i < s+sz; i++) { if(abs(vcc[i%sz]) > m) tot++; else ans[tot].pb(vcc[i%sz]); } } } printf("%d ", tot); for (int i = 1; i <= tot; i++) { printf("%d ", ans[i].size()); for (int j = 0; j < ans[i].size(); j++) printf("%d%c", ans[i][j], " "[j==ans[i].size()-1]); } } return 0; }
1004 Game
思路:考虑将游戏变成初始时只有2~n,如果先手必胜的话,那么先手第一步按这样取就获胜了;如果后手必胜的话,那么先手第一步取走1就获胜了。
所以无论先后手Alice必胜。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int n; while(cin >> n) puts("Yes"); return 0; }
1005 Hack It
思路:数论构造
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 3e3 + 100; int a[N][N], p = 47; int main() { fio; cout << 2000 << endl; for (int i = 0; i < p; i++) { for (int j = 0; j < p; j++) { for (int k = 0; k < p; k++) { a[i*p+j][k*p+(i+k*j)%p] = 1; } } } for (int i = 0; i < 2000; i++) { for (int j = 0; j < 2000; j++) printf("%d", a[i][j]); printf(" "); } return 0; }
1006 Matrix
1007 Naive Operations
思路:考虑只有当ai 为 bi 倍数时i这个位置才需要被更新,于是我们倒着减bi,当bi被减成0是,我们在i这个位置+1,重新将bi设为原来的bi
判断bi为不为0用线段树维护,答案用树状数组维护,复杂为nlog(n)^2,因为调和级数的和约为n*ln(n),所以最多更新nlog(n)次
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int INF = 0x3f3f3f3f; int b[N]; int mn[N*4], lazy[N*4], n; LL bit[N]; vector<int>vc; void add(int x) { while(x <= n) bit[x]++, x += x&-x; } LL sum(int x) { LL ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } void push_up(int rt) { mn[rt] = min(mn[rt<<1], mn[rt<<1|1]); } void push_down(int rt) { lazy[rt<<1] += lazy[rt]; lazy[rt<<1|1] += lazy[rt]; mn[rt<<1] += lazy[rt]; mn[rt<<1|1] += lazy[rt]; lazy[rt] = 0; } void build(int rt, int l, int r) { if(l == r) { lazy[rt] = 0; mn[rt] = b[l]; return ; } lazy[rt] = 0; int m = (l + r) >> 1; build(ls); build(rs); push_up(rt); } void update(int L, int R, int rt, int l, int r, int d) { if(L <= l && r <= R) { mn[rt] += d; if(mn[rt] == 0) { if(l == r) { vc.pb(l); } else { if(lazy[rt]) push_down(rt); int m = (l + r) >> 1; update(L, R, ls, d); update(L, R, rs, d); } } else lazy[rt] += d; return ; } if(lazy[rt]) push_down(rt); int m = (l+r) >> 1; if(L <= m)update(L, R, ls, d); if(R > m) update(L, R, rs, d); push_up(rt); } int query(int L, int R, int rt, int l, int r) { if(L <= l && r <= R) return mn[rt]; int ans = INF; int m = (l+r) >> 1; if(L <= m) ans = min(ans, query(L, R, ls)); if(R > m) ans = min(ans, query(L, R, rs)); return ans; } int main() { fio; string s; int q, l, r; while(cin >> n >> q) { for (int i = 1; i <= n; i++) cin >> b[i]; for (int i = 0; i <= n; i++) bit[i] = 0; build(1, 1, n); for (int i = 1; i <= q; i++) { cin >> s >> l >> r; if(s == "add") { update(l, r, 1, 1, n, -1); if(vc.size() > 0) { //cout << vc.size() << endl; for (int j = 0; j < vc.size(); j++) { add(vc[j]); update(vc[j], vc[j], 1, 1, n, b[vc[j]]); } vc.clear(); } } else { cout << sum(r) - sum(l-1) << endl; } } } return 0; }
1008 Odd Shops
1009 Segment
1010 Swaps and Inversions
思路:求个逆序数,再乘以最小花费
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>vc; int a[N], bit[N], n; void add(int x) { while(x <= n) bit[x] ++, x += x&-x; } int sum(int x) { int ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } int main() { int x, y; while(~ scanf("%d %d %d", &n, &x, &y)) { vc.clear(); for (int i = 0; i <= n; i++) bit[i] = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); vc.pb(a[i]); } sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 1; i <= n; i++) { a[i] = lower_bound(vc.begin(), vc.end(), a[i]) - vc.begin() +1; } LL tot = 0, ans; for (int i = 1; i <= n; i++) { tot += i - 1 - sum(a[i]); add(a[i]); } ans = min(x, y) * tot; printf("%lld ", ans); } return 0; }
2018 Multi-University Training Contest 3
1001 Problem A. Ascending Rating
思路:考虑到从前往后维护单调队列,维护的是单调递减的序列,与题目不符,于是我们从后往前维护单调队列,这样单调递减就变成单调递增了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e7 + 5; int a[N], nxt[N], tot[N]; int MOD; int main() { int T, n, m, k, p, q, r; scanf("%d", &T); while(T--) { scanf("%d%d%d%d%d%d%d", &n, &m, &k, &p, &q, &r, &MOD); for (int i = 1; i <= k; i++) scanf("%d", &a[i]); for (int i = k+1; i <= n; i++) a[i] = (1LL * p * a[i-1] + 1LL * q * i + r) % MOD; LL A = 0, B = 0; deque<int>q; for (int j = n; j >= 1; j--) { while(!q.empty() && a[q.back()] <= a[j]) q.pop_back(); q.push_back(j); while(!q.empty() && q.front() > j + m - 1) q.pop_front(); if(j <= n-m+1) { //cout << a[q.front()] << " " << q.size() << endl; A += a[q.front()] ^ j; B += ((int)q.size()) ^ j; } } printf("%lld %lld ", A, B); } return 0; }
1002 Problem B. Cut The String
1003 Problem C. Dynamic Graph Matching
思路:状压dp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 1e9 + 7; char s[15]; int dp[2][1100][10]; int n, m; int main() { int T, u, v; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); int now = 0; mem(dp, 0); for (int i = 0; i < (1<<n); i++) dp[now][i][0] = 1; while(m--) { scanf("%s %d %d", s, &u, &v); now ^= 1; int flag; if(s[0] == '+') flag = 1; else flag = -1; int mx = 0; for (int i = 0; i < (1<<n); i++) { dp[now][i][0] = 1; for (int j = 1; j <= n/2; j++) { if((i|(1<<u-1)|(1<<v-1)) == i)dp[now][i][j] = (dp[now^1][i][j] + flag * dp[now^1][i^(1<<u-1)^(1<<v-1)][j-1]) % MOD; else dp[now][i][j] = dp[now^1][i][j]; } } for (int i = 1; i <= n/2; i++) printf("%d%c", (dp[now][(1<<n)-1][i] + MOD) % MOD, " "[i==n/2]); } } return 0; }
1004 Problem D. Euler Function
1005 Problem E. Find The Submatrix
1007 Problem G. Interstellar Travel
1008 Problem H. Monster Hunter
1009 Problem I. Random Sequence
1010 Problem J. Rectangle Radar Scanner
1011 Problem K. Transport Construction
思路:构造
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) #p using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head char s[100][100]; int main() { int T, a, b, c; scanf("%d", &T); while(T--) { scanf("%d%d%d", &a, &b, &c); int n = (c+b) * 2 + 1; int m = (a+b) * 2 + 1; for (int i = 1; i <= n; i++) { if(i&1){ for (int j = 1; j <= m; j++) { if(j&1)s[i][j] = '+'; else s[i][j] = '-'; } } else { for (int j = 1; j <= m; j++) { s[i][j] = '.'; } } } for (int i = 1; i <= 2*b; i++) { for (int j = 1; j <= 2*b - i + 1; j++) { s[i][j] = '.'; s[n-i+1][m-j+1] = '.'; } } for (int i = 2*b + 2; i <= n; i += 2) { for (int j = 1; j <= 2*a; j += 2) { s[i][j] = '|'; } } int st = 2*b+2, ed = n; for (int i = 2*a + 1; i <= m; i += 2) { for (int j = st; j <= ed; j += 2) { s[j][i] = '|'; s[j][i+1] = '/'; s[j-1][i+1] = '.'; } st -= 2; ed -= 2; } for (int i = 2; i <= 2*b; i += 2) { for (int j = 2*b - i + 2; j <= 2*b - i + 2 + 2*a; j += 2) { s[i][j] = '/'; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } } return 0; }
2018 Multi-University Training Contest 4
1001 Problem A. Integers Exhibition
1002 Problem B. Harvest of Apples
思路:
我们打表发现组合数的和 和 组合数的递推 是一样的:sum(n, m) = sum(n-1, m) + sum(n-1, m-1)
对N进行分块,先预处理出每i*√N行的值,然后对于每个sum(n, m)我们都能在O(√N)时间以内递推出它的值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5, M = 350; const int MOD = 1e9 + 7; int blo = sqrt(N); vector<int>c[M]; int C[M][M], inv[N], tot = 0; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void init() { int cnt = 1; inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD; for (int i = 1; i < N; i += blo) { c[cnt].resize(i+blo+5); c[cnt][0] = 1; LL t = 1; for (int j = 1; j <= i; j++) { tot++; t = (t * (i-j+1)) % MOD; t = (t * inv[j]) % MOD; c[cnt][j] = (c[cnt][j-1] + t) % MOD; } for (int j = i+1; j <= i+blo; j++) c[cnt][j] = c[cnt][i]; cnt++; } C[0][0] = 1; for (int i = 1; i < M; i++) { for (int j = 1; j <= i; j++) C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD; } } int main() { init(); int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); int bl = (n-1)/blo; int base = bl*blo + 1; int dis = n - base + 1; int l = m - dis + 1, r = m; LL ans = 0; for (int i = l, j = 1; i <= r; i++, j++) { if(i < 0) continue; ans = (ans + 1LL*C[dis][j]*c[bl+1][i]%MOD) % MOD; } printf("%lld ", ans); } return 0; }
1003 Problem C. Problems on a Tree
1004 Problem D. Nothing is Impossible
思路:
贪心
如果仅有 1 道题,至少有一个人做对这题需要有 错误答案个数 + 1 个人。
我们将题目按错误答案个数从小到大排序,从错误答案个数小的开始回来,看最多回答了几个问题后存在1个人全对。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 222; pii a[N]; bool cmp(pii a, pii b) { return a.se < b.se; } int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%d %d", &a[i].fi, &a[i].se); } sort(a, a+n, cmp); int ans = 0; for (int i = 0; i < n; i++) { if(m >= 1 + a[i].se) { m = floor((double)m / (1 + a[i].se)); if(m >= 1) ans++; } } printf("%d ", ans); } return 0; }
1005 Problem E. Matrix from Arrays
思路:我们发现当n为奇数时是以n*n为循环,当n为偶数时是以2n * 2n为循环
于是我们打好2n * 2n的表,算好前缀和,注意处理好边界
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e3 + 5; int M[N][N], A[N]; LL sum[N][N] = {0}; int main() { fio; int T; cin >> T; while(T--) { int cursor = 0, n, q, x, y, x1, y1; cin >> n; for (int i = 0; i < n; i++) cin >> A[i]; for (int i = 0; i < 10*n; ++i) { for (int j = 0; j <= i; ++j) { M[j+1][i - j+1] = A[cursor]; cursor = (cursor + 1) % n; } } /*for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { cout << M[i][j] << " "; } cout<< endl; }*/ for (int i = 1; i <= 4*n; i++) { for (int j = 1; j <= 4*n; j++) { sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + M[i][j]; } } cin >> q; while(q--) { cin >> x >> y >> x1 >> y1; x++, y++, x1++, y1++; int h = (x1 - x + 1); int w = (y1 - y + 1); LL ans = 0; ans = 1LL * (w/(2*n)) * (h/(2*n)) * sum[2*n][2*n]; int w1 = w%(2*n); int h1 = h%(2*n); int xx = x%(2*n); int yy = y%(2*n); if(xx == 0) xx += 2*n; if(yy == 0) yy += 2*n; LL s1, s2, s3; if(w1) { int xxx = xx + 2*n - 1, yyy = yy + w1 - 1; s1 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s1 = 0; if(h1) { int xxx = xx + h1 - 1, yyy = yy + 2*n - 1; s2 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s2 = 0; if(w1 && h1) { int xxx = xx + h1 - 1, yyy = yy + w1 - 1; s3 = sum[xxx][yyy] - sum[xxx][yy-1] - sum[xx-1][yyy] + sum[xx-1][yy-1]; } else s3 = 0; ans += s1*(h/(2*n)) + s2 * (w/(2*n)) + s3; cout << ans << endl; } } return 0; }
1006 Problem F. Travel Through Time
1007 Problem G. Depth-First Search
1008 Problem H. Eat Cards, Have Fun
1009 Problem I. Delightful Formulas
1010 Problem J. Let Sudoku Rotate
思路:搜索剪枝
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 100; char s[N][N]; int g[N][N]; int t[N][N], ans; bool vis[16]; void Rotate(int x, int y) { for (int i = 1, a = y; i <= 4; i++, a++) { for (int j = 1, b = x+3; j <= 4; j++, b--) { t[i][j] = g[b][a]; } } for (int i = 1, a = x; i <= 4; i++, a++) { for (int j = 1, b = y; j <= 4; j++, b++) { g[a][b] = t[i][j]; } } } bool check(int x, int y) { for (int i = 1; i <= x; i++) { mem(vis, false); for (int j = 1; j <= y; j++) { if(vis[g[i][j]]) return false; else vis[g[i][j]] = true; } } for (int j = 1; j <= y; j++) { mem(vis, false); for (int i = 1; i <= x; i++) { if(vis[g[i][j]]) return false; else vis[g[i][j]] = true; } } return true; } void dfs(int pos, int tot) { if(pos == 16) { ans = min(ans, tot); return ; } for (int i = 0; i < 4; i++) { if(check(pos/4*4+4, pos%4*4+4)) dfs(pos+1, tot+i); Rotate(pos/4*4+1, pos%4*4+1); } } int main() { int T; scanf("%d", &T); while(T--) { for (int i = 1; i <= 16; i++) { scanf("%s", s[i]+1); } for (int i = 1; i <= 16; i++) { for (int j = 1; j <= 16; j++) { if(isdigit(s[i][j])) g[i][j] = s[i][j] - '0'; else g[i][j] = s[i][j] - 'A' + 10; } } ans = 16*3; dfs(0, 0); printf("%d ", ans); } return 0; }
1011 Problem K. Expression in Memories
思路:模拟
队友代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; bool check(char ch) { if(ch=='+'||ch=='*') return true; return false; } int main() { int n; scanf("%d",&n); while(n--) { string s; cin>>s; int len=s.size(); int ok=1; int flag=0; for(int i=0;i<len;i++) { if(i==0&&s[i]=='0'&&!check(s[i+1])&&i+1<len) { if(s[i+1]=='?') s[i+1]='+'; else { ok=0; break; } } if(check(s[i])&&s[i+1]=='0'&&!check(s[i+2])&&i+2<len) { if(s[i+2]=='?') s[i+2]='+'; else { ok=0; break; } } if(s[i]=='?') s[i]='5'; else if(check(s[i])&&check(s[i+1])) { ok=0; break; } } if(check(s[0])||check(s[len-1])) ok=0; if(!ok) printf("IMPOSSIBLE "); else cout<<s<<endl; } }
1012 Problem L. Graph Theory Homework
思路:
容易证明floor(sqrt(a)) + floor(sqrt(b)) > floor(sqrt(a+b))
所以最短路就是从1走到n
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e5 + 5; int a[N]; int main() { int n, T; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); printf("%d ", (int)sqrt(abs(a[1] - a[n]))); } return 0; }
2018 Multi-University Training Contest 5
1001 Always Online
1002 Beautiful Now
思路:暴力搜索
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head string s, a, b, ansmn, ansmx; int n, k; void dfs(int pos, int cnt) { if(cnt > k) return ; if(pos == n) { ansmn = min(ansmn, a); ansmx = max(ansmx, a); return ; } for (int i = pos; i < n; i++) { if(i == pos) { if(pos == 0 && a[i] == '0'); else { dfs(pos+1, cnt); } } else { if(pos == 0 && a[i] == '0'); else { swap(a[i], a[pos]); dfs(pos+1, cnt+1); swap(a[i], a[pos]); } } } } int main() { fio; int T; cin >> T; while(T--) { cin >> s >> k; n = s.size(); if(k >= n-1) { sort(s.begin(), s.end()); a = s; reverse(s.begin(), s.end()); b = s; for (int i = 0; i < n; i++) { if(a[i] != '0') { swap(a[0], a[i]); break; } } cout << a << " " << b << endl; } else { a = s; ansmn = a; ansmx = a; dfs(0, 0); cout << ansmn << " " << ansmx << endl; } } return 0; }
1004 Daylight
思路:余弦定理
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head int main() { int T, m; double R, x, y, r; scanf("%d", &T); while(T--) { scanf("%d %lf", &m, &R); double ans = 2 * pi * R; while(m--) { scanf("%lf %lf %lf", &x, &y, &r); double dd = x*x + y*y; if(sqrt(dd) > R + r || sqrt(dd) < R - r) continue; double sub = acos((R*R + dd - r*r) / (2*R*sqrt(dd))); double pls = acos((r*r + dd - R*R) / (2*r*sqrt(dd))); ans -= 2*sub*R; ans += 2*pls*r; } printf("%.10f ", ans); } return 0; }
1006 Fireflies
1007 Glad You Came
思路:线段树剪枝或者st表逆运用
线段树(700ms)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 1 << 30; int tree[N<<2], lazy[N<<2]; unsigned int X, Y, Z, t[5]; inline unsigned int f() { X ^= X << 11; X ^= X >> 4; X ^= X << 5; X ^= X >> 14; unsigned int W = X ^ (Y ^ Z); X = Y; Y = Z; Z = W; return Z; } inline void push_up(int rt) { tree[rt] = min(tree[rt<<1], tree[rt<<1|1]); } inline void push_down(int rt) { tree[rt<<1|1] = max(lazy[rt], tree[rt<<1|1]); tree[rt<<1] = max(lazy[rt], tree[rt<<1]); lazy[rt<<1|1] = max(lazy[rt], lazy[rt<<1|1]); lazy[rt<<1] = max(lazy[rt], lazy[rt<<1]); lazy[rt] = 0; } void build(int rt, int l, int r) { if(l == r) { tree[rt] = lazy[rt] = 0; return ; } lazy[rt] = tree[rt] = 0; int m = l+r >> 1; build(ls); build(rs); } inline void update(int L, int R, int v, int rt, int l, int r) { if(tree[rt] >= v) return ; if(L <= l && r <= R) { if(tree[rt] >= v) return ; else { if(l == r) tree[rt] = v, lazy[rt] = v; else { if(lazy[rt] < v) lazy[rt] = v; } return ; } } if(lazy[rt]) push_down(rt); int m = l+r >> 1; if(L <= m) update(L, R, v, ls); if(R > m) update(L, R, v, rs); push_up(rt); } inline int query(int p, int rt, int l, int r) { if(l == r) return tree[rt]; if(lazy[rt]) push_down(rt); int m = l+r >> 1; if(p <= m) return query(p, ls); else return query(p, rs); } int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z); build(1, 1, n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= 3; j++) t[j] = f(); int l = min(t[1]%n + 1, t[2]%n + 1); int r = max(t[1]%n + 1, t[2]%n + 1); int v = t[3] % MOD; update(l, r, v, 1, 1, n); } LL ans = 0; for (int i = 1; i <= n; i++) { int t = query(i, 1, 1, n); ans ^= (1LL * i * t); } printf("%lld ", ans); } return 0; }
st表(2200ms)跑的比我的线段树慢多了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const int MOD = 1 << 30; int st[N][20], Log[N]; unsigned int X, Y, Z, t[5]; inline unsigned int f() { X ^= X << 11; X ^= X >> 4; X ^= X << 5; X ^= X >> 14; unsigned int W = X ^ (Y ^ Z); X = Y; Y = Z; Z = W; return Z; } void init(int n) { for (int i = 1; i <= n; i++) { for (int j = 0; j < 19; j++) st[i][j] = 0; } } void update(int l, int r, int v) { int k = Log[r-l+1]; st[l][k] = max(st[l][k], v); st[r-(1<<k)+1][k] = max(st[r-(1<<k)+1][k], v); } void gao(int n) { for (int j = 18; j >= 1; j--) { for (int i = 1; i + (1<<j)-1 <= n; i++) { st[i][j-1] = max(st[i][j-1], st[i][j]); st[i+(1<<j-1)][j-1] = max(st[i+(1<<j-1)][j-1], st[i][j]); } } } int main() { int T, n, m; Log[2] = 1; for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1; scanf("%d", &T); while(T--) { scanf("%d %d %u %u %u", &n, &m, &X, &Y, &Z); init(n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= 3; j++) t[j] = f(); int l = min(t[1]%n + 1, t[2]%n + 1); int r = max(t[1]%n + 1, t[2]%n + 1); int v = t[3] % MOD; update(l, r, v); } gao(n); LL ans = 0; for (int i = 1; i <= n; i++) { int t = st[i][0]; ans ^= (1LL * i * t); } printf("%lld ", ans); } return 0; }
1008 Hills And Valleys
1009 Innocence
1010 Just So You Know
1011 Kaleidoscope
1012 Lost In The Echo
2018 Multi-University Training Contest 6
1001 oval-and-rectangle
思路:积一下分就可以了,注意保留6位小数,6位之后直接舍去,不要四舍五入,而且long double不能用printf输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { int T, a, b; scanf("%d", &T); while(T--) { scanf("%d %d", &a, &b); long double ans = (long double)2.0*(long double)a*asin((long double)1.0) + (long double)2.0*(long double)b; LL t = ans * 1000000; printf("%.6f ", t / (double)1000000.0); } return 0; }
1002 bookshelf
1003 Ringland
1004 Shoot Game
1005 black-and-white
1006 foam-transformation
1007 Variance-MST
1008 Rectangle Outline
1009 Werewolf
思路:首先,我们不能判断谁是村民,只能判断哪些人必定是狼,我们按类似2-sat的建边,不过是反向的,用dfs判断哪些点如果是村民,它一定会产生矛盾
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>g[N*2]; vector<int>st; int now, n, vis[N*2]; char s[50]; int dfs(int u, bool f) { if(f) vis[u] = true; for (int i = 0; i < g[u].size(); i++) { if(g[u][i] == now) dfs(g[u][i], true); else dfs(g[u][i], f); } } int main() { int T, x; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= 2*n; i++) g[i].clear(), vis[i] = false; st.clear(); for (int i = 1; i <= n; i++) { scanf("%d", &x); scanf("%s", s); if(s[0] == 'v') g[x].pb(i); else g[x+n].pb(i), st.pb(x+n); } int ans = 0; for (int i = 0; i < st.size(); i++) { now = st[i] - n; dfs(st[i], false); } for (int i = 1; i <= n; i++) if(vis[i]) ans++; printf("0 %d ", ans); } return 0; } /* 10 3 3 v 3 v 2 w 3 2 w 3 v 2 v 4 2 v 3 v 4 v 3 w */
1010 Chopping hands
1011 sacul
1012 Pinball
2018 Multi-University Training Contest 7
1001 Age of Moyu
1002 AraBellaC
1003 YJJ’s Stack
1004 Go to school
1005 GuGuFishtion
思路:容斥
首先,phi(n) = n * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是n的素因子
其中, phi(1) = 1
对于a和b两个数,如果它们都有一个公共的素因子p,假设 a 中有p ^ a1,b中有 p^a2
那么考虑这个素因子的贡献
phi(a * b) = (p - 1) * p ^ (a1 + a2 - 1) (1)
phi(a) * phi(b) = (p - 1) ^ 2 * p ^ (a1 + a2 - 2) (2)
那么 (1)/ (2) = p / (p -1)
如果a 和 b 每个共同的素因子 p, 即a1 和 a2 中有一个是0
那么 (1)/ (2)= 1,没有贡献
那么只需考虑 gcd(a, b) 的贡献即可
我们要求 p1 * p2 * .. * pn / ((p1 - 1) * (p2 - 1) * ... * (pn - 1)) ,其中pi是 gcd(a, b) 的素因子
我们看一下phi(gcd(a, b))等于什么
phi(gcd(a, b)) = gcd(a, b) * ((p1 - 1) / p1) * ((p2 - 1) / p2) * ... * ((pn - 1) / pn) 其中 pi 是gcd(a, b)的素因子
所以我们要求的就等于 (1 / phi(gcd(a, b))) * gcd(a, b) = gcd(a, b) / phi(gcd(a, b)
然后问题就转换成 1 <= a <= n , 1 <= b <= m 中有多少对gcd(a, b) == k
这个可以用容斥求:
假设f[d] = d | gcd(a, b) 的个数
假设g[d] = d == gcd(a, b) 的个数
则 g[d] = f[d] - sum(g[i*d], i >= 2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = 1e6 + 5; bool not_pr[N]; int pr[N/5], phi[N], inv[N], f[N]; void get_phi() { phi[1] = 1; int tot = 0; for (int i = 2; i < N; i++) { if(!not_pr[i]) { phi[i] = i-1; pr[tot++] = i; } for (int j = 0; i * pr[j] < N; j++) { not_pr[i*pr[j]] = true; if(i % pr[j] == 0) { phi[i*pr[j]] = phi[i] * pr[j]; break; } else phi[i*pr[j]] = phi[i] * phi[pr[j]]; } } } int main() { get_phi(); int T, n, m, mod; inv[1] = 1; scanf("%d", &T); while(T--) { scanf("%d %d %d", &n, &m, &mod); if(n > m) swap(n, m); for (int i = 2; i <= n; i++) inv[i] = (mod - mod/i) * 1LL * inv[mod%i] % mod; LL ans = 0; for (int i = n; i >= 1; i--) { f[i] = (1LL * (n/i) * (m/i)) % mod; for (int j = i+i; j <= n; j += i) f[i] = (f[i] - f[j] + mod) % mod; ans = (ans + 1LL * f[i] * i % mod * inv[phi[i]] % mod) % mod; } printf("%lld ", ans); } return 0; }
1006 Lord Li's problem
1007 Reverse Game
1008 Traffic Network in Numazu
1009 Tree
1010 Sequence
思路:我们发现有连续的一段 p/i 是一样的,而且p/i的不同个数是√p级别的,于是我们分段进行矩阵快速幂
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 1e9 + 7; const int N = 2e5 + 5; int dp[N]; struct Matrix { int a[3][3]; void init() { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) a[i][j] = 0; } } void _init() { init(); for (int i = 0; i < 3; i++) a[i][i] = 1; } }A, B; Matrix mul(Matrix a, Matrix b) { Matrix ans; ans.init(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if(a.a[i][j]) { for (int k = 0; k < 3; k++) ans.a[i][k] = (ans.a[i][k] + 1LL * a.a[i][j] * b.a[j][k]) % MOD; } } } return ans; } Matrix q_pow(Matrix a, int k) { Matrix ans; ans._init(); if(k <= 0) return ans; while(k) { if(k&1) ans = mul(ans, a); a = mul(a, a); k >>= 1; } return ans; } int main() { int T, a, b, c, d, p, n; scanf("%d", &T); A.init(); A.a[0][2] = 1; A.a[1][0] = 1; A.a[2][2] = 1; B.init(); while(T--) { scanf("%d %d %d %d %d %d", &a, &b, &c, &d, &p, &n); dp[1] = a; dp[2] = b; if(n <= 50000) { for (int i = 3; i <= n; i++) dp[i] = (1LL * c * dp[i-2] + 1LL * d *dp[i-1] + p/i) % MOD; printf("%d ", dp[n]); } else { A.a[0][0] = d; A.a[0][1] = c; B.a[0][0] = dp[2]; B.a[1][0] = dp[1]; for (int i = 3; i <= n;) { int j; if(p/i == 0) j = n; else j = min(n, p/(p/i)); B.a[2][0] = p/i; B = mul(q_pow(A, j-i+1), B); i = j+1; } printf("%d ", B.a[0][0]); } } return 0; }
1011 Swordsman
2018 Multi-University Training Contest 8
1001 Character Encoding
思路:生成函数+广义二项式定理
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const long long mod=998244353; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } long long inv[200010],fac[200010],nfac[200010],ninv[200010]; void getFac(){ fac[0]=1,nfac[0]=1; for(int i=1;i<=200000;i++)fac[i]=fac[i-1]*i%mod; for(int i=1;i<=200000;i++)nfac[i]=(mod+nfac[i-1]*(-i)%mod)%mod; inv[200000]=POW(fac[200000],mod-2); ninv[200000]=POW(nfac[200000],mod-2); for(int i=200000;i>=1;i--)inv[i-1]=inv[i]*i%mod,ninv[i-1]=(mod+ninv[i]*(-i)%mod)%mod; } long long C(long long n,long long m){ if(m<0)return 0; long long re=inv[m]; // re=inv[m]*(n>0?fac[n]:nfac[-n])%mod*(n-m>0?inv[n-m]:ninv[m-n])%mod; if(n>=0&&m>=0)re=re*fac[n]%mod*inv[n-m]%mod; else if(n<0&&m>=0)re=re*ninv[-n-1]%mod*nfac[m-n-1]%mod; // for(int i=0;i<m;i++)re=(re*(n-i)%mod+mod)%mod; // for(int i=1;i<=m;i++)re=(re*(POW(i,mod-2))%mod+mod)%mod; return re; } long long sign(long long x){ if(x&1)return -1; else return 1; } int main(){ int T; getFac(); cin>>T; long long n,m,k; for(int t=1;t<=T;t++){ scanf("%lld%lld%lld",&n,&m,&k); long long ans=0; for(long long i=0;i<=m;i++){ (ans+=C(m,i)*sign(m-i)*C(-m,k-i*n)*sign(-m-k+i*n)%mod+mod)%=mod; } cout<<(ans+mod)%mod<<endl; } return 0; }
1002 Pizza Hub
1003 City Development
1004 Parentheses Matrix
思路:首先,当n和m都是奇数时一个goodness都没有,随便构造,其次,当n和m中有一个是偶数时,所有行或者所有列都是构造成匹配的
当n和m都为偶数时(假设n > m),可以这样构造:
我们发现这样构造的的goodness是 n + (m - 2) / 2
我们还可以这样构造(牺牲最上面一行和最下面一行以及最左边一列和最右边一列来成全中间的所有行和列):
这样构造的goodness是 n + m - 4
解个不等式: n + (m - 2) / 2 >= n + m - 4
得: m <= 6
综上所述:
当min(n, m) <= 6 时,采用第一种构造;当min(n, m) > 6时,采用第二种构造
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 222; char s[N][N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d", &n, &m); if(n%2 == 0 && m%2 == 0 && min(n, m) > 6) { for (int i = 1; i <= m; i++) s[1][i] = '(', s[n][i] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) { for(int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } else { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } continue; } if(n < m) { if(n%2 == 0) { for (int j = 1; j <= m; j++) { if(j&1) { s[1][j] = '('; s[n][j] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int i = 1; i <= n; i++) { if(i&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else if(m%2 == 0) { for (int i = 1; i <= n; i++) { if(i&1) { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) s[i][j] = '('; } } } else { if(m%2 == 0) { for (int i = 1; i <= n; i++) { if(i&1) { s[i][1] = '('; s[i][m] = ')'; for (int j = 2; j < m; j++) { if((j-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int j = 1; j <= m; j++) { if(j&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else if(n%2 == 0) { for (int j = 1; j <= m; j++) { if(j&1) { s[1][j] = '('; s[n][j] = ')'; for (int i = 2; i < n; i++) { if((i-1)&1) s[i][j] = '('; else s[i][j] = ')'; } } else { for (int i = 1; i <= n; i++) { if(i&1) s[i][j] = '('; else s[i][j] = ')'; } } } } else { for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) s[i][j] = '('; } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar(s[i][j]); } puts(""); } } return 0; }
1005 Magic Square
1006 Boolean 3-Array
1007 Card Game
1008 K-Similar Strings
1009 Make ZYB Happy
1010 Taotao Picks Apples
思路:先用二分+st表采用dp求出每个位置往后的递增序列长度(对于dp[i],二分找到后面第一个比a[i]大的数a[j],然后dp[i] = dp[j] + 1)
再预处理出原序列到当前位置的递增序列的值以及长度,然后对于每个询问p和q,考虑将a[p]改变成q的影响来求答案
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const int INF = 0x7f7f7f7f; int a[N], dp[N], mx[N][20], v[N], pre[N], Log[N]; void init(int n) { for (int i = 0; i < 19; i++) { for (int j = 1; j + (1<<i) - 1 <= n; j++) { if(i == 0) mx[j][i] = a[j]; else mx[j][i] = max(mx[j][i-1], mx[j+(1<<i-1)][i-1]); } } } int query(int l, int r) { int k = Log[r-l+1]; return max(mx[l][k], mx[r-(1<<k)+1][k]); } int main() { int T, n, M, p, q; scanf("%d", &T); Log[2] = 1; for (int i = 3; i < N; i++) Log[i] = Log[i>>1] + 1; while(T--) { scanf("%d%d", &n, &M); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); a[n+1] = INF; dp[n+1] = 0; init(n); for (int i = n; i >= 1; i--) { int l = i+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(i+1, m) > a[i]) r = m; else l = m+1; m = l+r >> 1; } dp[i] = dp[m] + 1; } v[0] = 0, pre[0] = 0; for (int i = 1; i <= n; i++) { if(a[i] > v[i-1]) { v[i] = a[i]; pre[i] = pre[i-1] + 1; } else v[i] = v[i-1], pre[i] = pre[i-1]; } for (int i = 0; i < M; i++) { scanf("%d %d", &p, &q); int ans = pre[p-1]; if(q > v[p-1]) { ans++; int l = p+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(p+1, m) > q) r = m; else l = m+1; m = l+r >> 1; } ans += dp[m]; } else { int l = p+1, r = n+1, m = l+r >> 1; while(l < r) { if(query(p+1, m) > v[p-1]) r = m; else l = m+1; m = l+r >> 1; } ans += dp[m]; } printf("%d ", ans); } } return 0; }
1011 Pop the Balloons
1012 From ICPC to ACM
2018 Multi-University Training Contest 9
1001 Rikka with Nash Equilibrium
思路:dp,用滚动数组优化一下空间
从大到小填数字,dp[now][i][j]表示当前填了now个数字,选中了i行和j列的方案数
具体转移看代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 85; int mod; int dp[2][N][N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d %d %d", &n, &m, &mod); for (int i = 0; i < 2; i++) { for (int j = 0; j <= n; j++) { for (int k = 0; k <= m; k++) dp[i][j][k] = 0; } } int now = 0; dp[now][1][1] = (n*m) % mod; for (int i = 2; i <= n*m; i++) { for (int j = 1; j <= n; j++) { for (int k = 1; k <= m; k++) { dp[now^1][j][k] = 0; dp[now^1][j][k] = (dp[now^1][j][k] + 1LL * k * (n - j + 1) * dp[now][j-1][k] + 1LL * j * (m - k + 1) * dp[now][j][k-1]) % mod; dp[now^1][j][k] = (dp[now^1][j][k] + (j*k - (i-1)) * 1LL * dp[now][j][k]) % mod; } } now ^= 1; } printf("%lld ", dp[now][n][m] % mod); } return 0; }
1002 Rikka with Seam
1003 Rikka with APSP
1004 Rikka with Stone-Paper-Scissors
思路:公式 (a' * (c - b) + b' * (a - c) + c' * (b - a)) / (a + b + c)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll>pii; pii getAns(ll a,ll b,ll c,ll aa,ll bb,ll cc){ ll fi=aa*(c-b)+bb*(a-c)+cc*(b-a); ll se=a+b+c; return pii(fi,se); } int main(){ long long T; cin>>T; long long a,b,c,aa,bb,cc; for(int t=1;t<=T;t++){ cin>>a>>b>>c>>aa>>bb>>cc; pii ans=getAns(a,b,c,aa,bb,cc); ll gcd= __gcd(abs(ans.first),ans.second); if(gcd==ans.second){ cout<<ans.first/gcd<<endl; } else cout<<ans.first/gcd<<'/'<<ans.second/gcd<<endl; } return 0; }
1005 Rikka with Rain
1007 Rikka with Treasure
1010 Rikka with Time Complexity
1011 Rikka with Badminton
思路:
容斥推出公式:2^a * ((b+d+1)* 2^c + 2^b - (b+1))
一个不行的加起来,减去两个都不行的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int MOD = 998244353; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { int T, a, b, c, d;; scanf("%d", &T); while(T--) { scanf("%d %d %d %d", &a, &b, &c, &d); LL ans = q_pow(2, a) * 1LL * ( q_pow(2, c) * 1LL *(b + d + 1) % MOD + q_pow(2, b) - (1+b) + MOD) % MOD; printf("%lld ", ans); } return 0; }
2018 Multi-University Training Contest 10
1001 Problem A.Alkane
1002 Problem B. Beads
1003 Problem C. Calculate
1005 Problem E. TeaTree
思路:bitset瞎搞
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; vector<int>g[N]; vector<int>f[N]; int v[N], ans[N]; void init() { for (int i = 1; i < N; i++) { for (int j = i; j < N; j += i) { f[j].pb(i); } } } bitset<N> dfs(int u) { bitset<N> res; for (int t : f[v[u]]) res.set(N - t); ans[u] = -1; for (int v : g[u]) { bitset<N> t = dfs(v); ans[u] = max(ans[u], (int)(N - (res&t)._Find_first())); res |= t; } return res; } int main() { int n, u; init(); scanf("%d", &n); for (int i = 2; i <= n; i++) { scanf("%d", &u); g[u].pb(i); } for (int i = 1; i <= n; i++) scanf("%d", &v[i]); dfs(1); for (int i = 1; i <= n; i++) { if(ans[i] <= 0) printf("-1 "); else printf("%d ", ans[i]); } return 0; }
1007 Problem G. Cyclic
思路:打表找规律
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=998244353; ll a[100005]; void get_num() { a[1]=1; a[2]=0; a[3]=1; a[4]=1; a[5]=8; a[6]=36; for(ll i=7;i<=100000;i++) { a[i]=(((i-2)*a[i-1])%mod+((i-1)*a[i-2])%mod+((i&1)?1:-1))%mod; } // for(int i=1;i<=20;i++) cout<<a[i]<<endl; } int main() { int t; scanf("%d",&t); get_num(); while(t--) { int n; scanf("%d",&n); // n-=4; cout<<a[n]<<endl; } }
1008 Problem H. Pow
思路:高精度,用pow(2,n)也可以,跟计算机存储浮点数存储方式有关
double指数位可以从- 2^10 到 2^10 - 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.util.*; import java.lang.*; import java.io.*; import java.math.*; /* Name of the class has to be "Main" only if the class is public. */ public class Main { public static void main (String[] args) { Scanner reader = new Scanner(System.in); int T, n; T = reader.nextInt(); while(T != 0) { T--; n = reader.nextInt(); BigInteger ans = new BigInteger("1"); for (int i = 1; i <= n; i++) { ans = ans.multiply(BigInteger.valueOf(2)); } System.out.println(ans); } // your code goes here } }
1009 Problem I. Count
思路:打表找规律,与欧拉函数有关
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 20000100; int phi[N], prime[N/5]; LL ans[N]; bool not_prime[N]; void Euler() { phi[1]=1; int k=0; for(int i=2;i< N;i++) { if(!not_prime[i]) { phi[i]=i-1; prime[k++]=i; } for(int j=0; i*prime[j] < N; j++) { not_prime[i*prime[j]]=true; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } } int main() { Euler(); ans[0] = 0; for (int i = 1; i < N; i++) { if(i&1) ans[i] = ans[i-1] + phi[i]/2; else ans[i] = ans[i-1] + phi[i]; } int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); printf("%lld ", ans[n]); } return 0; }
1010 Problem J. CSGO
思路:用二进制枚举绝对值去掉后每个数前面的加减号。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 10; const LL INF = 0x3f3f3f3f3f3f3f3f; struct node { int s; int x[5]; }a[N], b[N]; bool cmp1(node a, node b) { return a.s < b.s; } bool cmp2(node a, node b) { return a.x[0] < b.x[0]; } bool cmp3(node a, node b) { return a.x[1] < b.x[1]; } bool cmp4(node a, node b) { return a.x[2] < b.x[2]; } bool cmp5(node a, node b) { return a.x[3] < b.x[3]; } bool cmp6(node a, node b) { return a.x[4] < b.x[4]; } LL mxa[50], mna[50], mxb[50], mnb[50]; int main() { int T; scanf("%d", &T); while(T--) { int n, m, k; scanf("%d %d %d", &n, &m, &k); for (int i = 0; i < (1<<k); i++) mxa[i] = mxb[i] = -INF, mna[i] = mnb[i] = INF; for (int i = 1; i <= n; i++) { scanf("%d", &a[i].s); for (int j = 0; j < k; j++) { scanf("%d", &a[i].x[j]); } for (int j = 0; j < (1<<k); j++) { LL t = a[i].s; for (int l = 0; l < k; l++) { if(j & (1<<l)) t += a[i].x[l]; else t -= a[i].x[l]; } mna[j] = min(mna[j], t); mxa[j] = max(mxa[j], t); } } for (int i = 1; i <= m; i++) { scanf("%d", &b[i].s); for (int j = 0; j < k; j++) { scanf("%d", &b[i].x[j]); } for (int j = 0; j < (1<<k); j++) { LL t = b[i].s; for (int l = 0; l < k; l++) { if(j & (1<<l)) t += b[i].x[l]; else t -= b[i].x[l]; } mnb[j] = min(mnb[j], t); mxb[j] = max(mxb[j], t); } } int up = (1<<k) - 1; LL ans = 0; for (int j = 0; j < (1<<k); j++) { ans = max(ans, mna[j] + mnb[up^j]); ans = max(ans, mna[j] + mxb[up^j]); ans = max(ans, mxa[j] + mnb[up^j]); ans = max(ans, mxa[j] + mxb[up^j]); //cout << j << " " << ans << endl; } printf("%lld ", ans); } return 0; } /* 100 5 5 1 3 3 -5 0 0 -5 5 0 0 5 2 -4 5 0 0 5 -5 0 0 -5 */
1011 Problem K. Pow2
1012 Problem L.Videos
牛客
牛客网暑期ACM多校训练营(第一场)
思路:找规律
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e3 + 10; const int MOD = 1e9 + 7; LL dp[N][N], t[2*N][2*N]; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { t[1][1] = 3; for (int i = 2; i < 2*N; i++) t[1][i] = (t[1][i-1] + i+1) % MOD; for (int i = 2; i < N; i++) { for (int j = 1; j < N; j++) { if(j == 1) t[i][j] = t[j][i]; else { t[i][j] = (t[i][j-1] * t[1][i+j-1] % MOD * q_pow(t[1][j-1], MOD-2)) % MOD; } } } int n, m; while(~ scanf("%d %d", &n, &m)) { printf("%lld ", t[n][m]); } return 0; }
思路:状态压缩
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 100; pii e1[N], e2[N]; int n, m1, m2, ans; int vis[10][10], cnt[10], vs[10][10], a[10], t[10][10]; map<int, int>mp; int main() { while( ~ scanf("%d %d %d", &n, &m1, &m2)) { mem(vs, 0); mem(cnt, 0); for (int i = 0; i < m1; i++) { scanf("%d %d", &e1[i].fi, &e1[i].se); if(e1[i].fi > e1[i].se) swap(e1[i].fi, e1[i].se); vs[e1[i].fi][e1[i].se] = 1; } mem(vis, 0); for (int i = 0; i < m2; i++) { scanf("%d %d", &e2[i].fi, &e2[i].se); if(e2[i].fi > e2[i].se) swap(e2[i].fi, e2[i].se); vis[e2[i].fi][e2[i].se] = 1; } int sta = 0; for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { sta = sta * 2 + vis[i][j]; } } int ans = 0; mp.clear(); for (int i = 1; i <= n; i++) a[i] = i; do { int s = 0; for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { t[i][j] = 0; } } for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { if(vs[i][j]) { if(a[i] < a[j]) t[a[i]][a[j]] = 1; else t[a[j]][a[i]] = 1; } } } for (int i = 1; i <= n; i++) { for (int j = i+1; j <= n; j++) { s = s * 2 + t[i][j]; } } mp[s]++; }while(next_permutation(a+1, a+1+n)); for (auto it = mp.begin(); it != mp.end(); it++) { int s = it -> fi; if((s & sta) == s) ans++; } printf("%d ", ans); } return 0; } /* 3 1 2 1 3 1 2 1 3 4 2 3 1 2 1 3 4 1 4 2 4 3 */
E Removal
思路:莫队
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int a[N], cnt[N], blo, ans, res[N]; struct edge { int l, r, bl, id; bool operator < (const edge & t) const { if(bl == t.bl) return r < t.r; else return l < t.l; } }Q[N]; void add(int x) { if(!cnt[a[x]]) ans++; cnt[a[x]]++; } void ded(int x) { cnt[a[x]]--; if(!cnt[a[x]]) ans--; } int main() { int n, q; while( ~scanf("%d %d", &n, &q)) { blo = sqrt(n); mem(cnt, 0); ans = 0; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); if(!cnt[a[i]]) ans++; cnt[a[i]]++; } for (int i = 1; i <= q; i++) { scanf("%d %d", &Q[i].l, &Q[i].r); Q[i].id = i; Q[i].l ++; Q[i].r --; Q[i].bl = (Q[i].l - 1) / blo; } sort(Q+1, Q+1+q); int i = 1, l, r; for (i = 1; i <= q; i++) { if(Q[i].l <= Q[i].r) { l = Q[i].l+1; r = Q[i].l; break; } else res[Q[i].id] = ans; } for (; i <= q; i++) { while(l < Q[i].l) add(l++); while(l > Q[i].l) ded(--l); while(r < Q[i].r) ded(++r); while(r > Q[i].r) add(r--); //cout << l << " " << r << " " << ans << endl; res[Q[i].id] = ans; } for (int i = 1; i <= q; i++) printf("%d ", res[i]); } return 0; } /* 10 10 1 2 3 4 5 6 7 8 9 10 4 5 5 6 6 7 8 9 4 6 4 7 4 8 4 9 4 10 4 10 */
牛客网暑期ACM多校训练营(第二场)
A run
思路:dp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 1e9 + 7; LL dp[N][2], sum[N]; int main() { int q, k, l, r; scanf("%d %d", &q, &k); dp[0][0] = 1; for (int i = 1; i < N; i++) { dp[i][0] += dp[i-1][0] + dp[i-1][1]; dp[i][0] %= MOD; if(i - k >= 0) dp[i][1] += dp[i-k][0]; dp[i][1] %= MOD; } sum[0] = 1; for (int i = 1; i < N; i++) { sum[i] = (sum[i-1] + dp[i][0] + dp[i][1]) % MOD; } while(q--) { scanf("%d %d", &l, &r); printf("%lld ", ((sum[r] - sum[l-1]) % MOD + MOD) % MOD); } return 0; }
B discount
C message
D money
思路:贪心,每次找连续上升的一段
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int a[N]; int main() { int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); int pre = 1, cnt = 0, now = 0; LL ans = 0; for (int i = 2; i <= n; i++) { if(a[i] >= a[i-1]) { now = i; } else { if(now > pre && a[now] != a[pre]){ ans += a[now] - a[pre]; cnt += 2; } pre = i; } } if(now > pre && a[now] != a[pre]) ans += a[now] - a[pre], cnt += 2; printf("%lld %d ", ans, cnt); } return 0; }
E tree
F trade
思路:二分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 5; LL pren[N], pres[N], sufn[N], sufs[N]; int n; LL T; struct node { int x, a; bool operator < (const node & t) const { return x < t.x; } }a[N]; LL get_pres(int l, int r) { return pres[r] - pres[l] - (a[r].x - a[l].x) * pren[l]; } LL get_sufs(int l, int r) { return sufs[l] - sufs[r] - (a[r].x - a[l].x) * sufn[r]; } bool check(LL m) { int mid = 0, r = 0; LL cnt1 = (m+1)/2; for (int i = 1; i <= n; i++) { while(mid <= n && pren[mid] - pren[i-1] < cnt1) mid++; if(mid > n) break; while(r <= n && pren[r] - pren[i-1] < m) r++; if(r > n) break; if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[r].x - a[mid].x)) * 2 <= T) return true; if((get_pres(i-1, mid) + get_sufs(mid, r+1) - (pren[r] - pren[i-1] - m) * (a[i].x - a[mid].x)) * 2 <= T) return true; } // mid = r = n; // for (int i = n; i >= 1; i--) { // while(mid >= 1 && sufn[mid] - sufn[i+1] < cnt1) mid--; // if(mid < 1) break; // while(r >= 1 && sufn[r] - sufn[i+1] < m) r--; // if(r < 1) break; // if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (pren[i] - pren[r-1] - m) * (a[mid].x - a[r].x)) * 2 <= T) return true; // if((get_pres(r-1, mid) + get_sufs(mid, i+1) - (m - pren[i] + pren[r-1]) * (a[i].x - a[mid].x)) * 2 <= T) return true; // } return false; } int main() { scanf("%d %lld", &n, &T); for (int i = 1; i <= n; i++) scanf("%d", &a[i].x); for (int i = 1; i <= n; i++) scanf("%d", &a[i].a); sort(a+1, a+1+n); a[0].x = 0; for (int i = 1; i <= n; i++) { pren[i] = pren[i-1] + a[i].a; pres[i] = pres[i-1] + (a[i].x - a[i-1].x) * pren[i-1]; } a[n+1].x = 1000000000; for (int i = n; i >= 1; i--) { sufn[i] = sufn[i+1] + a[i].a; sufs[i] = sufs[i+1] + (a[i+1].x - a[i].x) * sufn[i+1]; } LL l = 0, r = 1e10, m = (l + r + 1) >> 1; while(l < r) { if(check(m)) l = m; else r = m-1; m = (l + r + 1) >> 1; // cout << l << " " << r << endl; } printf("%lld ", m); return 0; }
H travel
思路:树形dp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 4e5 + 5, M = 5; int a[N]; vector<int>g[N]; LL F[N][5], G[N][5]; void dfs(int o, int u) { LL sum[2][M][M] = {0}, tmp[M][M] = {0}; int now = 0; for (int v : g[u]) { if(v != o) { dfs(u, v); for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { tmp[i][j] = 0; sum[now][i][j] = 0; } } for (int i = 0; i <= 3; i++) { tmp[0][i] = F[v][i]; tmp[1][i] = G[v][i]; } for (int i = 0; i <= 2; i++) { for (int j = 0; i+j <= 2; j++) { for (int k = 0; k <= 3; k++){ for (int l = 0; l+k <= 3; l++) { sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][i][k] + tmp[j][l]); //sum[now][i+j][l+k] = max(sum[now][i+j][l+k], sum[now^1][j][l] + tmp[i][k]); } } } } now ^= 1; } } for (int i = 0; i <= 1; i++) { for (int j = 0; j <= 3; j++) { G[u][j] = max(G[u][j], sum[now^1][i][j] + a[u]); } } for (int i = 0; i <= 2; i++) { for (int j = 1; j <= 3; j++) { F[u][j] = max(F[u][j], sum[now^1][i][j-1] + a[u]); } } for (int i = 0; i <= 3; i ++) F[u][i] = max(F[u][i], sum[now^1][0][i]); } int main() { int n, u, v; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i < n; i++) { scanf("%d %d", &u, &v); g[v].pb(u); g[u].pb(v); } dfs(0, 1); printf("%lld ", F[1][3]); return 0; }
I car
思路:风车状
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; bool r[N], c[N]; int main() { int n, m, x, y; scanf("%d %d", &n, &m); for (int i = 0; i < m; i++) { scanf("%d %d", &x, &y); r[x] = true; c[y] = true; } int ans = 0; if(n % 2) { for (int i = 1; i <= n; i++) { if(i == n/2 + 1) continue; if(!r[i]) ans++; } for (int i = 1; i <= n; i++) { if(i == n/2 + 1) continue; if(!c[i]) ans++; } if(!r[n/2 + 1] || !c[n/2 + 1]) ans++; } else { for (int i = 1; i <= n; i++) if(!r[i]) ans++; for (int i = 1; i <= n; i++) if(!c[i]) ans++; } printf("%d ", ans); return 0; }
J farm
思路:随机或者树状数组
随机
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 5; vector<int>a[N]; vector<LL> s1[N], s2[N]; int b1[N], b2[N]; void add(int x, int y, int k) { s1[x][y] += b1[k]; s2[x][y] += b2[k]; } void del(int x, int y, int k) { s1[x][y] -= b1[k]; s2[x][y] -= b2[k]; } void cal(int x, int y) { s1[x][y] += s1[x-1][y] + s1[x][y-1] - s1[x-1][y-1]; s2[x][y] += s2[x-1][y] + s2[x][y-1] - s2[x-1][y-1]; } int main() { srand(time(NULL)); int n, m, T, x1, y1, x2, y2, k; scanf("%d %d %d", &n, &m, &T); for (int i = 0; i <= n+2; i++) a[i].resize(m+3), s1[i].resize(m+3), s2[i].resize(m+3); for (int i = 1; i < N; i++) { b1[i] = (random() % MOD) + N; b2[i] = (random() % MOD) + N/2; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) scanf("%d", &a[i][j]); } while(T--) { scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &k); add(x1, y1, k); del(x1, y2+1, k); del(x2+1, y1, k); add(x2+1, y2+1, k); } int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cal(i, j); if(s1[i][j] % b1[a[i][j]] == 0 && s2[i][j] % b2[a[i][j]] == 0) ans++; } } printf("%d ", n*m - ans); return 0; }
树状数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 5; vector<int> bit[N], id[N], t[N]; vector<bool>vis[N]; vector<pii>pos[N]; int n, m; struct query { int x1, x2, y1, y2; }Q[N]; void add(int x, int y, int t) { for (int i = x; i <= n; i += i&-i) { for (int j = y; j <= m; j += j&-j) { bit[i][j] += t; } } } int sum(int x, int y) { int ans = 0; for (int i = x; i; i -= i&-i) { for (int j = y; j; j -= j&-j) { ans += bit[i][j]; } } return ans; } int main() { int T, k, mx = 0, a; scanf("%d %d %d", &n, &m, &T); for (int i = 0; i <= n+2; i++) bit[i].resize(m+3), vis[i].resize(m+3), t[i].resize(m+3); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &a); pos[a].push_back({i, j}); mx = max(mx, a); } } for (int i = 0; i < T; i++) { scanf("%d %d %d %d %d", &Q[i].x1, &Q[i].y1, &Q[i].x2, &Q[i].y2, &k); id[k].push_back(i); mx = max(mx, k); } for (int i = 1; i <= mx; i++) { for (int j = 0; j < pos[i].size(); j++) { if(sum(pos[i][j].fi, pos[i][j].se) != 0) vis[pos[i][j].fi][pos[i][j].se] = true; } for (int j = 0; j < id[i].size(); j++) { add(Q[id[i][j]].x1, Q[id[i][j]].y1, 1); add(Q[id[i][j]].x1, Q[id[i][j]].y2 + 1, -1); add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y1, -1); add(Q[id[i][j]].x2 + 1, Q[id[i][j]].y2 + 1, 1); } for (int j = 0; j < pos[i].size(); j++) { if(!vis[pos[i][j].fi][pos[i][j].se]) { t[pos[i][j].fi][pos[i][j].se] = sum(pos[i][j].fi, pos[i][j].se); } } } int ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if(!vis[i][j]) { if(t[i][j] != sum(i, j)) ans++; } else ans++; } } printf("%d ", ans); return 0; }
K carpet
思路:hash+KMP找最小循环节,然后用二维单调队列求区间最小
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 1e9 + 7; const int INF = 0x7f7f7f7f; string s[N]; vector<int>cost[N], mx[N]; int row[N], col[N], nxt[N]; int get_loop(int a[], int n) { nxt[0] = -1; for (int i = 1; i < n; i++) { int j = nxt[i-1]; while(a[j+1] != a[i] && j >= 0) j = nxt[j]; if(a[j+1] == a[i]) nxt[i] = j+1; else nxt[i] = -1; } return n - (nxt[n-1]+1); } int main() { fio; int n, m; cin >> n >> m; for (int i = 0; i < n; i++) cin >> s[i]; for (int i = 0; i < n; i++) cost[i].resize(m+2), mx[i].resize(m+2); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) cin >> cost[i][j]; } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { row[i] = (233LL * row[i] + s[i][j]) % MOD; col[j] = (233LL * col[j] + s[i][j]) % MOD; } } int a = get_loop(col, m), b = get_loop(row, n); deque<int>q; for (int i = 0; i < n; i++) { q.clear(); for (int j = 0; j < m; j++) { while(!q.empty() && cost[i][q.back()] <= cost[i][j]) q.pop_back(); q.push_back(j); while(!q.empty() && q.front() < j - a + 1) q.pop_front(); mx[i][j] = cost[i][q.front()]; } } int ans = INF; for (int j = a-1; j < m; j++) { q.clear(); for (int i = 0; i < n; i++) { while(!q.empty() && mx[q.back()][j] <= mx[i][j]) q.pop_back(); q.push_back(i); while(!q.empty() && q.front() < i - b + 1) q.pop_front(); if(i >= b-1) { ans = min(ans, mx[q.front()][j]); } } } cout << 1LL * ans * (a+1) * (b+1) << endl; return 0; }
牛客网暑期ACM多校训练营(第三场)
思路:背包,用short类型开数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> #define fi first.first.first #define se first.first.second #define th first.second #define fo second using namespace std; const int maxn=40; int p[maxn],a[maxn],c[maxn],m[maxn],g[maxn]; short dp[38][38][38][38][38]; bool cat[38][38][38][38][38]; vector<int> ans; int main(){ int n; int P,A,C,M; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d%d%d%d",p+i,a+i,c+i,m+i,g+i); scanf("%d%d%d%d",&P,&A,&C,&M); int i,j,k,l,q; for(i=1;i<=n;i++) for(j=0;j<=P;j++) for(k=0;k<=A;k++) for(l=0;l<=C;l++) for(q=0;q<=M;q++){ if(j>=p[i]&&k>=a[i]&&l>=c[i]&&q>=m[i]){ cat[i][j][k][l][q]=1; dp[i][j][k][l][q]=dp[i-1][j-p[i]][k-a[i]][l-c[i]][q-m[i]]+g[i]; } if(dp[i-1][j][k][l][q]>=dp[i][j][k][l][q])dp[i][j][k][l][q]=dp[i-1][j][k][l][q],cat[i][j][k][l][q]=0; } short ansp,ansa,ansc,ansm; int maxans=0; for(int j=0;j<=P;j++) for(int k=0;k<=A;k++) for(int l=0;l<=C;l++) for(int q=0;q<=M;q++) if(dp[n][j][k][l][q]>maxans)ansp=j,ansa=k,ansc=l,ansm=q,maxans=dp[n][j][k][l][q]; if(maxans==0)return cout<<0,0; for(int i=n;i>=1;i--){ if(cat[i][ansp][ansa][ansc][ansm]){ ans.push_back(i); ansp-=p[i],ansa-=a[i],ansc-=c[i],ansm-=m[i]; } } cout<<ans.size()<<endl; for(int i=0;i<ans.size();i++)cout<<ans[i]-1<<' '; return 0; }
思路:splay实现区间反转
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define MAXN 100005 using namespace std; int read(){ char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0'; while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x; } int n,m,root; struct Splay{ int fa[MAXN],son[MAXN][2],siz[MAXN],add[MAXN]; void up(int k){ siz[k]=siz[son[k][0]]+siz[son[k][1]]+1; } void down(int k){ if(add[k]){ swap(son[k][0],son[k][1]); add[son[k][0]]^=1;add[son[k][1]]^=1; add[k]=0; } } void rotate(int x,int &k){ int f=fa[x],gran=fa[f],opt; opt=(son[f][1]==x); if(f==k) k=x;else son[gran][son[gran][1]==f]=x; son[f][opt]=son[x][opt^1];fa[son[f][opt]]=f; son[x][opt^1]=f;fa[f]=x;fa[x]=gran; siz[x]=siz[f];up(f); } void splay(int x,int &k){ while(x!=k){ int f=fa[x],gran=fa[f]; if(f!=k) rotate((son[f][0]==x)^(son[gran][0]==f)?x:f,k); rotate(x,k); } } void build(int l,int r,int f){ if(l>r) return; int mid=(l+r)>>1;if(mid<f) son[f][0]=mid;else son[f][1]=mid; fa[mid]=f;siz[mid]=1; if(l==r) return; build(l,mid-1,mid);build(mid+1,r,mid); up(mid); } int find(int x,int k){ down(x);int s=siz[son[x][0]]; if(s+1==k) return x; if(k<=s) return find(son[x][0],k); else return find(son[x][1],k-s-1); } void revers(int l,int r){ int x=find(root,l),y=find(root,r+2); splay(x,root);splay(y,son[root][1]); int pl=son[y][0];add[pl]^=1; } }T; int main() { n=read();m=read(); root=(n+3)>>1;T.build(1,n+2,root); for(int i=1;i<=m;i++){ int l=read(),r=read(); r=l+r-1; T.revers(1,l-1); T.revers(l,r); T.revers(1,r); } for(int i=2;i<=n+1;i++) printf("%d ",T.find(root,i)-1); return 0; }
思路:字符串hash+排序
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; typedef unsigned long long ULL; typedef pair<ULL,ULL> pll; typedef pair<int,int> pii; const int maxn=1000010; const int base=233; char s[maxn]; ULL POW[maxn]; pll Hash[maxn]; pii p[maxn]; vector<int> vec[maxn]; int main(){ scanf("%s",s); int n=strlen(s); ULL now=0; POW[0]=1; for(int i=1;i<=n;++i)POW[i]=POW[i-1]*base; for(int i=0;i<n;++i)now=now*base+(s[i]-'a'+1); for(int i=0;i<n;i++){ Hash[i]={now,(ULL)i}; now=now-(s[i]-'a'+1)*POW[n-1]; now=now*base+(s[i]-'a'+1); } sort(Hash,Hash+n); int anscnt=0; for(int i=0;i<n;i++){ if(!i||Hash[i-1].first!=Hash[i].first)++anscnt,p[anscnt]={Hash[i].second,anscnt}; vec[anscnt].emplace_back(Hash[i].second); } sort(p+1,p+1+anscnt); printf("%d ",anscnt); for(int i=1;i<=anscnt;i++){ printf("%d ",vec[p[i].second].size()); for(auto w:vec[p[i].second]){ printf("%d ",w); } puts(""); } return 0; }
思路:枚举小于n的素数,每个素数和比它小的素数匹配,最后答案乘2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e7 + 5; bool vis[N]; vector<int>p; void seive() { for (int i = 2; i < N; i++) { if(!vis[i]) { p.push_back(i); for (int j = i+i; j < N; j += i) vis[j] = true; } } } int main() { seive(); int n; scanf("%d", &n); LL ans = 0; for (int i = 0; i < p.size(); i++) { if(p[i] > n) break; ans += n/p[i] * 1LL * i; } ans *= 2; printf("%lld ", ans); return 0; }
I Expected Size of Random Convex Hull
牛客网暑期ACM多校训练营(第四场)
思路:构造,花了几个小时想了一个超复杂的构造TAT,看看别人的构造,感觉自己蠢哭了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 555; int a[N][N]; map<int, int>mp; bool check(int n) { mp.clear(); for (int i = 1; i <= n; i++) { int s = 0; for (int j = 1; j <= n; j++) { s += a[i][j]; } mp[s]++; } for (int i = 1; i <= n; i++) { int s = 0; for (int j = 1; j <= n; j++) { s += a[j][i]; } mp[s]++; } if(mp.size() == n*2) return true; else return false; } int main() { fio; int T, n; cin >> T; while(T--) { cin >> n; if(n&1) { cout << "impossible" << endl; continue; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) a[i][j] = -1; } for (int i = 1; i <= n/2; i++) { for (int j = 1; j <= n/2; j++) { a[i][j] = 1; a[i+n/2][j+n/2] = -1; if(i + j > n/2 + 1) a[i][j+n/2] = 0; else a[i][j+n/2] = 1; } } int tot = n/2, cnt, res; if(tot&1) cnt = tot/2+1; else cnt = tot/2; res = tot - cnt; for (int i = 1; i <= cnt; i++) { for (int j = 1; j <= cnt; j++) { if(i + j > cnt + ((tot+1)%2)) a[i+tot][j] = 0; else a[i+tot][j] = 1; } } for (int i = 1; i <= res; i++) { for (int j = 1; j <= res; j++) { if(i + j > res) a[i+tot+cnt][j+cnt] = 0; else a[i+tot+cnt][j+cnt] = -1; } } cout << "possible" << endl; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) cout << a[i][j] << " "; cout << endl; } } return 0; }
E Skyline
思路:模拟
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; char s[2005][2005]; bool check(char a,char b, char c,char d) { if(a==b&&a==c&&a==d) return true; return false; } int main() { int t; while(scanf("%d",&t)!=EOF) { while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",s[i]); int Maxc=INT_MAX; int Maxr=INT_MAX; for(int i=0;i<n;i++) { int cnt=0; for(int j=0;j<m/2;j++) { if(s[i][j]==s[i][m-j-1]) cnt++; else { cnt++; break; } } Maxr=min(Maxr,cnt); } for(int i=0;i<m;i++) { int cnt=0; for(int j=0;j<n/2;j++) { if(s[j][i]==s[n-j-1][i]) cnt++; else { cnt++; break; } } Maxc=min(Maxc,cnt); } Maxc--; Maxr--; printf("%d ",Maxc*Maxr); } } }
思路:统计一下出现次数为i的数的个数,然后从小到大枚举数a[i],检查一下将所有出现次数大于等于a[i]出现次数的数删掉成都小于a[i]的个数,可行就更新答案。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5 ; int a[N]; int t[N]; LL sum[N]; int main() { int T, n, m; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%d", &a[i]); for (int i = 0; i <= n; i++) t[i] = 0; sort(a, a+n); int now = 1; for (int i = 1; i < n; i++) { if(a[i] != a[i-1]) { t[1]++; t[now+1]--; now = 1; } else now++; } t[1]++; t[now+1]--; now = 1; for (int i = 1; i <= n; i++) t[i] += t[i-1]; for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + t[i]; int ans = -1; for (int i = 1; i < n;i++) { if(a[i] != a[i-1]) { if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[i-1]; now = 1; } else now++; } if(t[now] - 1 + sum[n] - sum[now] <= m) ans = a[n-1]; printf("%d ", ans); } return 0; }
A gpa
思路:01分数规划
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const double eps = 1e-7; int n, k; pii a[N]; double t[N]; bool check(double m) { for (int i = 0; i < n; i++) t[i] = (double)a[i].fi*a[i].se - m*a[i].fi; sort(t, t+n); double tt = 0; for (int i = k; i < n; i++) tt += t[i]; //cout<< fixed << setprecision(6)<< tt << endl; return tt >= 0; } int main() { scanf("%d %d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &a[i].fi); for (int i = 0; i < n; i++) scanf("%d", &a[i].se); double l = 0, r = 1e4 + 5, m = (l+r)/2; while(l + eps< r) { if(check(m)) l = m; else r = m; m = (l+r) / 2; } printf("%.10f ", m); return 0; }
B div
C grf
D inv
E room
F take
思路:考虑每个位置对答案的贡献,但前位置被替换当且仅当前面所有比当前小的都没有被替换(即之前比当前小的盒子的钻石都没有钻石,有1-pj的概率),这个用树状数组维护个前缀积就可以了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 998244353; pii a[N]; LL bit[N]; int n; vector<int>vc; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void add(int x, LL y) { while(x <= n) bit[x] *= y, bit[x] %= MOD, x += x&-x; } LL sum(int x) { LL ans = 1; while(x) ans *= bit[x], ans %= MOD, x -= x&-x; return ans; } int main() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se); sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 0; i < n; i++) a[i].fi = (1LL * a[i].fi * q_pow(100, MOD-2)) % MOD, a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin(), a[i].se = n - a[i].se; for (int i = 0; i <= n; i++) bit[i] = 1; LL ans = 0; for (int i = 0; i < n; i++) { ans = (ans + a[i].fi * sum(a[i].se - 1)) % MOD; add(a[i].se, (1 - a[i].fi) % MOD); } ans = (ans + MOD) % MOD; printf("%lld ", ans); return 0; }
G max
思路:找第一个i和n互质,质数之间距离很短
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int main() { fio; int c, n; cin >> c >> n; n /= c; for (int i = n; i >= 1; i--) { if(__gcd(i, n) == 1) { cout << 1LL * n * i * c * c << endl; return 0; } } cout << -1 << endl; return 0; }
H subseq
I vcd
思路:首先,一个点的集合肯定可以,其次,二个点如果想满足题意,那么y要求不同,三点的集合如果想满足题意,那么要三个点构成“<”形状,最后,超过三个点的集合都不可以。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; const int MOD = 998244353; pii a[N]; vector<int>vc; int n, t[N], bit[N]; void add(int x) { while(x <= n) bit[x]++, x += x&-x; } int sum(int x) { int ans = 0; while(x) ans += bit[x], x -= x&-x; return ans; } bool cmp(pii a, pii b) { return a.fi > b.fi; } LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d %d", &a[i].fi, &a[i].se), vc.pb(a[i].se); sort(vc.begin(), vc.end()); vc.erase(unique(vc.begin(), vc.end()), vc.end()); for (int i = 1; i <= n; i++) a[i].se = lower_bound(vc.begin(), vc.end(), a[i].se) - vc.begin() + 1, t[a[i].se]++; sort(a+1, a+1+n, cmp); LL ans = 0; for (int i = 1; i <= n; i++) ans += 1LL*t[i]*(n-t[i]), ans %= MOD; ans = (ans * q_pow(2, MOD-2)) % MOD; ans = (ans + n) % MOD; int pos = 1; for (int i = 1; i <= n; i++) { if(a[i].fi != a[i-1].fi) { while(pos < i) { add(a[pos++].se); } } int up = sum(n) - sum(a[i].se); int down = sum(a[i].se - 1); ans += 1LL * up * down; ans %= MOD; } printf("%lld ", ans); return 0; }
J plan
思路:答案肯定是某一种房间选了很多,我们暴力房间少的那一个,3个就够了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
牛客网暑期ACM多校训练营(第六场)
思路:模拟+贪心,每次歌手都唱大于对方最大值的歌
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e4 + 5; set<int>s[N]; int mx[N]; bool vis[N]; int main() { int T, n, t; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%d", &n); mem(mx, 0); for (int i = 1; i <= (1<<n); i++) { s[i].clear(); for (int j = 1; j <= n; j++) { scanf("%d", &t); s[i].insert(t); mx[i] = max(mx[i], t); } } mem(vis, false); for (int i = 1; i <= n; i++) { int last = -1; for (int j = 1; j <= (1<<n); j++) { if(!vis[j]) { if(last == -1) last = j; else { int mm = mx[last], mmm = mx[j]; if(mm > mmm) { vis[j] = true; auto it = s[last].lower_bound(mmm); s[last].erase(it); mx[last] = 0; for (auto t : s[last]) mx[last] = max(mx[last], t); } else { vis[last] = true; auto it = s[j].lower_bound(mm); s[j].erase(it); mx[j] = 0; for (auto t : s[j]) mx[j] = max(mx[j], t); } last = -1; } } } } for (int i = 1; i <= (1<<n); i++) if(!vis[i]) { printf("Case #%d: %d ", cs, i); break; } } return 0; }
思路:考虑第i次操作i ~ n的所有集合都加相同的数,所以我们只考虑每个数第一次出现在哪里,因为如果这个数在后面有没有出现过是没有关系的,后面的所有集合都有这个数
考虑总共出现了k个数,第一个位置肯定出现了一个数,所以从n-1个位置中选k-1个位置,再加上第一个位置构成k个位置,作为这k个数第一次出现的位置,总共有C(n-1, k-1)中
然后考虑这k个数有多少种可能,有A(m, k)可能,所以对于出现k个数,有C(n-1, k-1) * A(m, k)中可能,然后将k从1枚举min(n, m)求个和就可以了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e6 + 5; const int MOD = 998244353; int inv[N]; void init() { inv[1] = 1; for (int i = 2; i < N; i++) inv[i] = (MOD - MOD/i) * 1LL * inv[MOD%i] % MOD; } int main() { init(); int T; LL n, m; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%lld %lld", &n, &m); int up = min(n, m); LL ans = 0, C = 1, A = m%MOD; for (int i = 1; i <= up; i++) { ans = (ans + C * A) % MOD; n--; m--; C = ((C * n) % MOD * inv[i]) % MOD; A = (A * m) % MOD; } printf("Case #%d: %lld ", cs, ans); } return 0; }
思路:发现每个身体只能连一个头,所以对于每个身体选一个最大的权值,它连哪个头都无所谓,这样是最优的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e5 + 5; int mx[N]; int main() { int T, a, b, c, n, m, k; scanf("%d", &T); for (int cs = 1; cs <= T; cs++) { scanf("%d %d %d", &n, &m, &k); for (int i = 1; i <= n; i++) mx[i] = 0; for (int i = 0; i < k; i++) { scanf("%d %d %d", &a, &b, &c); mx[b] = max(c, mx[b]); } LL ans = 0; for (int i = 1; i <= m; i++) ans += mx[i]; printf("Case #%d: %lld ", cs, ans); } return 0; }
F Squirtle
G Pikachu
H Eevee
思路:由于数据随机,所以最大的几个数有很大可能互质,所以挑出最大的几个数两两求lcm取最大,可以用stl里面的nth_element(),很强大
如果用set的话,注意保存一下当前set的最小值,与最小值判断一下需不需要加进set,否则的化常数太大会超时
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; typedef long long ll; unsigned int A,B,C; unsigned int x=A,y=B,z=C; inline unsigned int tang() { unsigned int t; x^=x<<16; x^=x>>5; x^=x<<1; t=x; x=y; y=z; z=t^x^y; return z; } unsigned int num[10000005]; set<unsigned int>mx; inline unsigned long long gcd(unsigned long long a, unsigned long long b) { return b ? gcd(b, a%b): a; } inline unsigned long long lcm(unsigned long long x,unsigned long long y) { return x/__gcd(x,y)*y; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t; cin>>t; for(int tt=1;tt<=t;tt++) { int n; cin>>n>>A>>B>>C; x=A,y=B,z=C; mx.clear(); unsigned int mn; for(int i=1;i<=n;i++) { num[i]=tang(); if(mx.size() < 20) mx.insert(num[i]), mn = *mx.begin(); else { if(num[i] > mn) { mx.insert(num[i]); mx.erase(mx.begin()); mn = *mx.begin(); } } } unsigned long long Max=0; vector<unsigned int>vc; for (auto x:mx) vc.push_back(x); for (int i = 0; i < vc.size(); i++) { for (int j = i+1; j < vc.size(); j++) { Max = max(Max, lcm(vc[i], vc[j])); } } cout<<"Case #"<<tt<<": "<<Max<<endl; } return 0; }
牛客网暑期ACM多校训练营(第七场)
A Minimum Cost Perfect Matching
思路:对于每个i找比i小的~i,将两个连接起来,这样最小花费是0
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 5; bool vis[N]; int a[N]; int main() { int n; scanf("%d", &n); for (int i = n - 1; i >= 0; i--) { int t = 0; bool f = false; for (int j = 29; j >= 0; j--) { if((i & (1 << j)) == 0) { if(f) t = t*2 + 1; } else { f = true; t = t*2; } } if(!vis[i] && !vis[t]) { a[i] = t; a[t] = i; vis[t] = true; vis[i] = true; } } for (int i = 0; i < n; i++) printf("%d%c", a[i], " "[i==n]); return 0; }
思路:搜索优化,预处理出最后三步的结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb emplace_back #define pf emplace_front #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = (1<<16) + 10, M = (1<<20) + 10; bool t[20][M]; char s[M]; int dp[5][N], ans = 0; void init(int n) { int up = 1; for (int i = 0; i < n; i++) up = up * 3; for (int i = 0; i < (1<<(1<<n)); i++) { for (int j = 0; j < (1<<n); j++) { if(i & (1<<j)) t[n][j] = 1; else t[n][j] = 0; } for (int j = 0; j < up; j++) { int tmp = j; for (int k = n-1; k >= 0; k--) { for (int l = 0; l < (1<<k); l++) { if(tmp%3 == 0) t[k][l] = t[k+1][l*2]^t[k+1][l*2+1]; else if(tmp%3 == 1) t[k][l] = t[k+1][l*2]&t[k+1][l*2+1]; else t[k][l] = t[k+1][l*2]|t[k+1][l*2+1]; } tmp /= 3; } dp[n][i] += t[0][0]; } } } void dfs(int n) { for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]^t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; } else dfs(n-1); for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]&t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; } else dfs(n-1); for (int i = 0; i < (1<<n); i++) t[n][i] = t[n+1][i*2]|t[n+1][i*2+1]; if(n == 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + t[n][i]; ans += dp[n][st]; return ; } else dfs(n-1); } int main() { int n; scanf("%d", &n); scanf("%s", s); init(min(n, 3)); if(n <= 3) { int st = 0; for (int i = 0; i < (1<<n); i++) st = st*2 + (s[i] == '1'); printf("%d ", dp[n][st]); } else { for (int i = 0; i < (1<<n); i++) t[n][i] = s[i] == '1'; dfs(n-1); printf("%d ", ans); } return 0; }
思路:打表可以发现当k很大时可以由t个点的完全图加上另外5个点与t个点中的部分点相连构成k个4元组,即存在t, a, b, c, d, e,
使得C(t, 4) + C(a, 3) + C(b, 3) + C(c, 3) + C(d, 3)+ C(e, 3) == k
预处理C(e, 3), 暴力枚举a,b, c, d
或者预处理C(d, 3) + C(e, 3) , 暴力枚举a,b, c
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head int C4[100], C3[100], t; int C(int n, int m) { int ans = 1; if(n < m) return 0; for (int i = n; i >= n-m+1; i--) ans *= i; for (int i = 1; i <= m; i++) ans /= i; return ans; } void solve(int a, int b, int c, int d, int e) { printf("%d %d ", t+5, C(t, 2) + a + b + c + d + e); for (int i = 1; i <= t; i++) { for (int j = i+1; j <= t; j++) printf("%d %d ", i, j); } for (int i = 1; i <= a; i++) printf("%d %d ", i, t+1); for (int i = 1; i <= b; i++) printf("%d %d ", i, t+2); for (int i = 1; i <= c; i++) printf("%d %d ", i, t+3); for (int i = 1; i <= d; i++) printf("%d %d ", i, t+4); for (int i = 1; i <= e; i++) printf("%d %d ", i, t+5); } map<int, pii>mp; int main() { int k; scanf("%d", &k); t = 4; for (int i = 3; i <= 80; i++) C4[i] = C(i, 4), C3[i] = C(i, 3); while(C4[t+1] <= k) t++; t = min(t, 70); for (int i = 2; i <= t; i++) { for (int j = 2; j <= t; j++) { mp[C3[i] + C3[j]] = {i, j}; } } for (int i = 2; i <= t; i++) { for (int j = i; j <= t; j++) { for (int l = j; l <= t; l++) { if(mp.find(k - C4[t] - C3[i] - C3[j] - C3[l]) != mp.end()) { solve(i, j, l, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].fi, mp[k - C4[t] - C3[i] - C3[j] - C3[l]].se); return 0; } } } } return 0; }
G Rock-Paper-Scissors Tournament
思路:O(n*m)处理每个点往右能到哪里,往下能到哪里,然后O(52*n*m)对于每个点往右扫列最小,然后往下求行最小
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int N = 1e3 + 5; char s[N][N]; int a[N][N], r[N][N], d[N][N], mn[N][N]; int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%s", s[i]+1); for (int j = 1; j <= m; j++) if(isupper(s[i][j])) a[i][j] = s[i][j] - 'A' + 26; else a[i][j] = s[i][j] - 'a'; } for (int i = 1; i <= n; i++) { LL st = 0; int pre = 1; for (int j = 1; j <= m; j++) { if(j > 1) st ^= 1LL << a[i][j-1]; r[i][j] = m; bool f = true; for (int k = pre; k <= m; k++) { if(st & (1LL << a[i][k])) { f = false; r[i][j] = k-1; pre = k; break; } st |= 1LL << a[i][k]; } if(f) pre = m+1; } } for (int j = 1; j <= m; j++) { LL st = 0; int pre = 1; for (int i = 1; i <= n; i++) { if(i > 1) st ^= 1LL << a[i-1][j]; d[i][j] = n; bool f = true; for (int k = pre; k <= n; k++) { if(st & (1LL << a[k][j])) { f = false; d[i][j] = k-1; pre = k; break; } st |= 1LL << a[k][j]; } if(f) pre = n+1; } } LL ans = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { mn[i][j] = d[i][j]; for (int k = j+1; k <= r[i][j]; k++) { mn[i][k] = min(mn[i][k-1], d[i][k]); } int now = r[i][j]; for (int k = i; k <= d[i][j]; k++) { now = min(now, r[k][j]); while(mn[i][now] < k && now >= j) now --; if(now < j) break; ans += now - j + 1; } } } printf("%lld ", ans); return 0; }
oeis公式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 998244353; const int N = 3e5 + 5; LL C[N], NN[N], inv[N], p[N], ans = 0; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } void init(int n) { n--; inv[1] = 1; for (int i = 2; i <= n; i++) inv[i] = (MOD - MOD/i) * inv[MOD%i] % MOD; p[0] = 1; for (int i = 1; i <= n; i++) p[i] = (p[i-1] * 2) % MOD; C[0] = 1; for (int i = 1; i <= n; i++) C[i] = ((C[i-1] * (n-i+1)) % MOD * inv[i]) % MOD; for (int i = 1; i <= n; i++) NN[i] = (C[i] * C[i-1]) % MOD * inv[n] % MOD; for (int i = 1; i <= n; i++) ans = (ans + NN[i] * p[n-i+1]) % MOD; } int main() { int n; scanf("%d", &n); if(n == 1) return 0*puts("1"); init(n); printf("%lld ", ans); return 0; }
思路:立体几何欧拉公式:V - E + F = 2 (V:顶点个数, E:边条数, F:面个数,怎么记忆呢,维数为0的点加上维数为2的面减去维数为1的线等于2)
F = E - V + 2
首先,将平面图看成立体图(以正多边形为底的立体图),那么问题就转换成已知点个数和边条数来求多面体的面有多少个
内部交点个数(从n个点中选4个顶点连起来):C(n, 4)
所以定点个数:C(n, 4) + n
每个内部交点会多产生两条边,所以边个数: C(n, 2) + C(n, 4) * 2
所以F = E - V + 2 = (C(n, 2) + C(n, 4) * 2) - (C(n, 4) + n) + 2 = C(n, 2) + C(n, 4) - n + 2
减去底面所以要减一
答案为C(n, 2) + C(n, 4) - n + 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout); //head const int MOD = 1e9 + 7; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } LL C(int n, int m) { LL ans = 1; for (int i = n; i >= n-m+1; i--) ans = (ans * i) % MOD; for (int i = 1; i <= m; i++) ans = (ans * q_pow(i, MOD-2)) % MOD; return ans; } int main() { int n; cin >> n; LL ans = (C(n, 4) + C(n, 2) - n + 1 + MOD) % MOD; cout << ans << endl; return 0; }
牛客网暑期ACM多校训练营(第九场)
思路:FWT
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define int long long int n,a[530000],b[530000],tot,x,ha=1e9+7,inv2; int qpow(int a,int b) { int ans=1; while(b){if(b&1)ans=ans*a%ha;a=a*a%ha,b>>=1;} return ans; } void fwt(int *a,int n,int t) { for(int i=1;i<n;i<<=1) { for(int j=0;j<n;j+=(i<<1)) for(int k=j;k<i+j;k++) { int x=a[k],y=a[k+i]; a[k]=(x+y)%ha,a[k+i]=(x-y+ha)%ha; if(t)a[k]=a[k]*inv2%ha,a[k+i]=a[k+i]*inv2%ha; } } } signed main() { scanf("%lld",&n); inv2=qpow(2,ha-2); for(int i=0;i<n;i++)scanf("%lld",&a[i]); for(int i=0;i<n;i++)scanf("%lld",&b[i]); fwt(a,n,0);fwt(b,n,0); for(int i=0;i<n;i++)b[i]=b[i]*qpow(a[i],ha-2)%ha; fwt(b,n,1); for(int i=0;i<n;i++)printf("%lld ",b[i]); return 0; }
B Enumeration not optimization
C Gambling
思路:dp
状态定义:dp[i][0]表示到第i位以0结尾的期望分数,dp[i][1]表示到第i位以1结尾的期望分数
状态转移:dp[i][0] = (1 - p[i]) * (dp[i-1][0] + dp[i-1][1])
dp[i][1] = ∑ ( ∏p[k](j < k <= i) * (dp[j][0] + (1 - p[j]) * (i - j)^m)) (0<= j < i)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e3 + 5; const int MOD = 1e9 + 7; LL p[N], pp[N], dp[N][2]; LL q_pow(LL n, LL k) { LL ans = 1; while(k) { if(k&1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main() { int n, m; scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%lld", &p[i]); for (int i = 0; i <= n; i++) p[i] = (p[i] * q_pow(100, MOD-2)) % MOD, pp[i] = (1 - p[i] + MOD) % MOD; dp[0][0] = dp[1][0] = 0; for (int i = 1; i <= n; i++) { LL t = p[i]; dp[i][1] = 0; for (int j = i-1; j >= 0; j--) { dp[i][1] = (dp[i][1] + t * (dp[j][0] + pp[j] * q_pow(i-j, m) % MOD) % MOD) % MOD; t = (t * p[j]) % MOD; } dp[i][0] = (pp[i] * (dp[i-1][0] + dp[i-1][1])) % MOD; } printf("%lld ", (dp[n][1] + dp[n][0]) % MOD); return 0; }
思路:KMP
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; long long dp[1010][2]; int nnxt[5][100010]; int ans[100010]; void init(int MIN){ for(int i=0;i<=100010;i++)ans[i]=MIN; } void getNext(string ptr, int next[]){ next[0] = -1; int j = 0, k = -1; while(j < ptr.size()){ if (k == -1 || ptr[j] == ptr[k]){ if (ptr[++j] == ptr[++k]) next[j] = next[k]; else next[j] = k; } else k = next[k]; } } int I[100010],J[100010]; bool match[100010]; int KMP(string now, string ptr,int next[]){ string str; int cnt = 0; int i = 0, j = 0; int pos = 0; while(pos < now.length()){ if(now[pos]=='-'){ if(str.length())str.pop_back(); i=I[str.length()],j=J[str.length()]; cnt+=match[str.length()]; pos++; if(match[str.length()])ans[pos]=0; else ans[pos]=min(ans[pos],(int)ptr.length()-j); // cout<<j<<' '; continue; } else{ str.push_back(now[pos]); match[str.length()]=0; while(i < str.size()){ if (j == -1 || str[i] == ptr[j]){ i++, j++; if (j == ptr.size()){ cnt++; j = next[j]; match[str.length()]=1; ans[pos+1]=0; //cout<<j<<endl; } } else j = next[j]; } I[str.length()]=i,J[str.length()]=j; pos++; ans[pos]=min(ans[pos],(int)ptr.length()-j); // cout<<j<<' '; } } return cnt; } int main(){ int n; string t[5]; string s; int MIN=0x7fffffff; cin>>n; for(int i=1;i<=n;i++){ cin>>t[i]; getNext(t[i],nnxt[i]); MIN=min(MIN,(int)t[i].length()); } init(0x7fffffff); cin>>s; for(int i=1;i<=n;i++){ // cout<<" "; KMP(s,t[i],nnxt[i]); // cout<<endl; // // cout<<endl; } cout<<MIN<<endl; for(int i=1;i<=s.length();i++)cout<<ans[i]<<endl; return 0; }
J Maze
牛客网暑期ACM多校训练营(第十场)
思路:每次修改后这个位置的期望值不变,因为加上一个lowbit和减去一个lowbit后取平均值还是原来的值。
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const long long mod=998244353; long long a[100010]; long long pre[100010]; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } int main(){ int T; int n,m; int u,v,w; scanf("%d",&T); for(int t=1;t<=T;t++){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%lld",a+i); } for(int i=1;i<=n;i++){ pre[i]=(pre[i-1]+a[i])%mod; } long long pp=POW(2ll,1ll*n*m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); if(u==2){ printf("%lld ",((pre[w]-pre[v-1]+mod)%mod)*pp%mod); } } } return 0; }
B Rikka with Burrow-Wheeler Transform
思路:推出每个位置i的k阶前缀和的公式∑C(i+k-1, k)*a[j] (1 <= j <= i),然后用差分记录第一种操作的修改(不然保存不下),将差分看成-1阶的前缀和,然后查询的时候将所有出现过的修改都用公式求一下前缀和查询到修改之间有几次第二种操作就是他的阶数,记得要加1,因为我们用差分记录的。
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; long long fac[200010],inv[200010]; const long long mod=998244353; int L[200010],R[200010],val[200010],cnt[200010],top,tot; long long POW(long long x,long long n){ long long re=1,base=x; while(n){ if(n&1)(re*=base)%=mod; (base*=base)%=mod; n>>=1; } return re; } long long C(long long n,long long m){ if(n<0||m<0||n<m)return 0; return fac[n]*inv[n-m]%mod*inv[m]%mod; } void init(){ top=0,tot=0; } void INIT(){ fac[0]=1; for(int i=1;i<=200001;i++)fac[i]=fac[i-1]*i%mod; inv[200001]=POW(fac[200001],mod-2); for(int i=200001;i>=1;i--)inv[i-1]=inv[i]*i%mod; } int main(){ INIT(); int T,n,m,op; int l,r,v; scanf("%d",&T); for(int t=1;t<=T;t++){ init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d%d%d",&l,&r,&v); L[top]=l,R[top]=r,val[top]=v,cnt[top++]=tot; } else if(op==2)tot++; else{ long long ans=0; scanf("%d%d",&l,&r); for(int j=0;j<top;j++){ ans+= C(r-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod +C(r-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod -C(l-1-L[j]+tot-cnt[j]+1,tot-cnt[j]+1)*val[j]%mod -C(l-1-R[j]-1+tot-cnt[j]+1,tot-cnt[j]+1)*(-val[j])%mod; ((ans%=mod)+=mod)%=mod; } cout<<ans<<endl; } } } return 0; }
思路:记录下每个字母的位置,然后合并时查找第一个可行的位置,然后更新可行区间。
队友代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; int idx(char c){ return c-'a'; } vector<int> pos[26]; int getPos(int id,int p){ if(lower_bound(pos[id].begin(),pos[id].end(),p)==pos[id].end())return -1; else return pos[id][lower_bound(pos[id].begin(),pos[id].end(),p)-pos[id].begin()]; } void init(){ for(int i=0;i<26;i++)pos[i].clear(); } char ans[1000010]; char s[1000010]; int main(){ int T,n,m; scanf("%d",&T); for(int t=1;t<=T;t++){ scanf("%d",&n); int tot=0; init(); for(int i=1;i<=n;i++){ scanf("%s",s); m=strlen(s); int ppos=0; for(int j=0;j<m;j++){ if(ppos==-1){ pos[idx(s[j])].push_back(tot); ans[tot++]=s[j]; } else{ ppos=(getPos(idx(s[j]),ppos)); if(ppos==-1){ pos[idx(s[j])].push_back(tot); ans[tot++]=s[j]; } else{ ppos++; } } } } ans[tot]=0; puts(ans); } return 0; }