Replay
Dup4:
- 没想清楚就动手写? 写了两百行发现没用?想的还是不够仔细啊。
- 要有莽一莽的精神
X:
- 感觉今天没啥输出啊, 就推了个公式?抄了个板子, 然后就一直自闭A。
- 语文差,题目没理解,导致写了接近三小时的A吧, 最后看了一眼群, 发现自己理解错了。
- 以及感觉自己最近不会交流,有点毒瘤了。
A:二十四点*
Solved.
思路:
Div2 暴力跑?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 int n; 6 double arr[20]; 7 8 int main() 9 { 10 while(~scanf("%d", &n)) 11 { 12 for(int i = 1; i <= n; ++i) scanf("%lf", arr + i); 13 else if(n == 6) puts("32"); 14 else if(n == 10) puts("891"); 15 16 } 17 return 0; 18 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 typedef long long ll; 5 const ll MOD = 998244353; 6 const double eps = 1e-8; 7 8 int n, ans; 9 double arr[12]; 10 double brr[12]; 11 12 int DFS(int len) 13 { 14 if (len == 1) 15 { 16 if (fabs(brr[1] - 24.0) < eps) return 1; 17 else return 0; 18 } 19 20 for (int i = 1; i <= len; ++i) 21 { 22 for (int j = i + 1; j <= len; ++j) 23 { 24 double a = brr[i], b = brr[j], c = brr[len]; 25 brr[j] = c; 26 double tmp = a + b; 27 brr[i] = tmp; 28 if (fabs(tmp - 24.0) < eps) return 1; 29 if (DFS(len - 1)) return 1; 30 31 tmp = a - b; 32 brr[i] = tmp; 33 if (fabs(tmp - 24.0) < eps) return 1; 34 if (DFS(len - 1)) return 1; 35 36 tmp = b - a; 37 brr[i] = tmp; 38 if (fabs(tmp - 24.0) < eps) return 1; 39 if (DFS(len - 1)) return 1; 40 41 tmp = a * b; 42 brr[i] = tmp; 43 if (fabs(tmp - 24.0) < eps) return 1; 44 if (DFS(len - 1)) return 1; 45 46 tmp = a / b; 47 brr[i] = tmp; 48 if (fabs(tmp - 24.0) < eps) return 1; 49 if (DFS(len - 1)) return 1; 50 51 tmp = b / a; 52 brr[i] = tmp; 53 if (fabs(tmp - 24.0) < eps) return 1; 54 if (DFS(len - 1)) return 1; 55 56 57 brr[i] = a, brr[j] = b, brr[len] = c; 58 } 59 } 60 61 return 0; 62 } 63 64 void RUN() 65 { 66 while (~scanf("%d", &n)) 67 { 68 for (int i = 1; i <= n; ++i) scanf("%lf", arr + i); 69 ans = 0; 70 for (int i = 0; i < (1 << n); ++i) 71 { 72 int tot = 0; 73 for (int j = 0; j < n; ++j) 74 { 75 if (i & (1 << j)) 76 { 77 brr[++tot] = arr[j + 1]; 78 } 79 } 80 int tmp = DFS(tot); 81 ans += tmp; 82 } 83 printf("%d\n", ans); 84 } 85 } 86 87 int main() 88 { 89 RUN(); 90 return 0; 91 }
F:小清新数论*
Solved.
思路:
$ans = \sum\limits_{d = 1}^n \cdot \mu(d) \sum\limits_{i = 1}^{\frac{n}{d}} \sum\limits_{j = 1}^{\frac{n}{d}} [gcd(i, j) == 1]$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 const ll MOD = 998244353; 8 const int maxn = 1e7 + 10; 9 10 bool check[maxn]; 11 int prime[maxn]; 12 int mu[maxn]; 13 ll sum[maxn]; 14 15 void Moblus() 16 { 17 mu[1] = 1; 18 int tot = 0; 19 for(int i = 2; i < maxn; ++i) 20 { 21 if(!check[i]) 22 { 23 prime[tot++] = i; 24 mu[i] = -1; 25 } 26 for(int j = 0; j < tot; ++j) 27 { 28 if(i * prime[j] > maxn) break; 29 check[i * prime[j]] = true; 30 if(i % prime[j] == 0) 31 { 32 mu[i * prime[j]] = 0; 33 break; 34 } 35 else 36 { 37 mu[i * prime[j]] = -mu[i]; 38 } 39 } 40 } 41 for(int i = 1; i < maxn; ++i) 42 { 43 sum[i] = (sum[i - 1] + mu[i]) % MOD; 44 } 45 } 46 47 ll solve(int n, int m) 48 { 49 ll ans = 0; 50 if(n > m) swap(n, m); 51 for(int i = 1, la = 0; i <= n; i = la + 1) 52 { 53 la = min(n / (n / i), m / (m / i)); 54 ans += (sum[la] - sum[i - 1]) * (n / i) * (n / i); 55 } 56 return ans; 57 } 58 59 int n; 60 61 int main() 62 { 63 Moblus(); 64 while(~scanf("%d", &n)) 65 { 66 ll ans = 0; 67 for(int i = 1; i <= n; ++i) 68 { 69 ans = (ans + mu[i] * solve(n / i, n / i) % MOD + MOD) % MOD; 70 } 71 printf("%lld\n", ans); 72 } 73 return 0; 74 }
G:排列
Solved.
签到。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 int n, q[N], p[N], vis[N]; 6 7 int main() 8 { 9 while (scanf("%d", &n) != EOF) 10 { 11 memset(vis, 0, sizeof vis); 12 memset(p, 0, sizeof p); 13 for (int i = 1; i <= n; ++i) scanf("%d", q + i); 14 int j = 1; 15 for (int i = 1; i <= n; ++i) 16 { 17 if (i == 1 || q[i] < q[i - 1]) 18 { 19 vis[j] = 1; 20 p[q[i]] = j; 21 ++j; 22 } 23 } 24 for (int i = 1; i <= n; ++i) if (!p[i]) 25 p[i] = j++; 26 for (int i = 1; i <= n; ++i) printf("%d%c", p[i], " \n"[i == n]); 27 } 28 return 0; 29 }
H:涂鸦*
Solved.
思路:
对于某一个点来说,它被染成黑点的概率是$\frac{(x - l + 1) \cdot (r - x + 1) \cdot 2}{(r - l + 1) \cdot (r - l + 2)}$
然后二维BIT维护矩形,最后将所有未被矩形覆盖的期望加起来即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 1010 6 const ll p = (ll)998244353; 7 const ll MOD = (ll)998244353; 8 int n, m, q; 9 ll inv[N]; 10 int ans[N][N]; 11 12 namespace BIT 13 { 14 int a[N][N]; 15 void init() { memset(a, 0, sizeof a); } 16 void update(int x, int y, int v) 17 { 18 for (int i = x; i > 0; i -= i & -i) 19 for (int j = y; j > 0; j -= j & -j) 20 a[i][j] += v; 21 } 22 int query(int x, int y) 23 { 24 int res = 0; 25 for (int i = x; i < N; i += i & -i) 26 for (int j = y; j < N; j += j & -j) 27 res += a[i][j]; 28 return res; 29 } 30 void update(int x1, int y1, int x2, int y2) 31 { 32 update(x1 - 1, y1 - 1, 1); 33 update(x1 - 1, y2, -1); 34 update(x2, y1 - 1, -1); 35 update(x2, y2, 1); 36 } 37 } 38 39 int main() 40 { 41 inv[1] = 1; 42 for (int i = 2; i < N; ++i) inv[i] = inv[p % i] * (p - p / i) % p; 43 while (scanf("%d%d%d", &n, &m, &q) != EOF) 44 { 45 memset(ans, 0, sizeof ans); BIT::init(); 46 for (int i = 1, l, r; i <= n; ++i) 47 { 48 scanf("%d%d", &l, &r); 49 for (int j = l; j <= r; ++j) 50 ans[i][j] = 2ll * (j - l + 1) %p * (r - j + 1) %p * inv[r - l + 1] % p * inv[r - l + 2] % p; 51 //cout << ans[i][l] * (r - l + 1) * (r - l + 2) / 2 % p << endl; 52 } 53 for (int qq = 1; qq <= q; ++qq) 54 { 55 int x1, x2, y1, y2; 56 scanf("%d%d%d%d", &x1, &y1, &x2, &y2); 57 BIT::update(x1, y1, x2, y2); 58 } 59 ll res = 0; 60 for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (!BIT::query(i, j)) 61 { 62 //cout << i << " " << j << endl; 63 res = (res + ans[i][j]) % p; 64 } 65 printf("%lld\n", res); 66 } 67 return 0; 68 }
I:石头剪刀布
Solved.
思路:
考虑有$x之前要被a个人挑战,要挑战b个人$
那么$此时对于x满足的方案数是3^n \cdot \frac{1}{3}^b \cdot \frac{2}{3}^a$
然后考虑怎么维护$a和b$
我们发现对于1操作
我们将$y 接在 x 下面的话,这样最后会构成一棵树$
那么$b就是祖宗的个数$
再考虑$a是什么,我们发现其实就是 它的所有祖先当中 所有比它后加入的儿子个数 以及它所有的儿子个数$
然后再发现一棵子树对其他点的影响,发现受影响的点就是它的父亲中比它先来的儿子中所对应的所有子树
这一段在$DFS序中是连续的,线段树维护即可$
刚开始错误思路,写了个树剖,喵喵喵?
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 200010 6 const ll MOD = (ll)998244353; 7 int n, m, fa[N]; 8 vector <int> G[N]; 9 struct qnode 10 { 11 int op, x, y; 12 void scan() 13 { 14 scanf("%d%d", &op, &x); ++x; 15 if (op == 1) 16 { 17 scanf("%d", &y); ++y; 18 fa[y] = x; 19 G[x].push_back(y); 20 } 21 } 22 }q[N]; 23 24 int deep[N], sze[N], top[N], son[N], lp[N], rp[N], fp[N], cnt; 25 void DFS(int u) 26 { 27 sze[u] = 1; 28 for (auto v : G[u]) if (v != fa[u]) 29 { 30 deep[v] = deep[u] + 1; 31 DFS(v); 32 sze[u] += sze[v]; 33 if (!son[u] && sze[v] > sze[son[u]]) son[u] = v; 34 } 35 } 36 37 void getpos(int u, int sp) 38 { 39 top[u] = sp; 40 lp[u] = ++cnt; 41 fp[cnt] = u; 42 if (!son[u]) 43 { 44 rp[u] = cnt; 45 return; 46 } 47 getpos(son[u], sp); 48 for (auto v : G[u]) if (v != fa[u] && v != son[u]) 49 getpos(v, v); 50 rp[u] = cnt; 51 } 52 53 namespace SEG 54 { 55 struct node 56 { 57 int v[2], lazy[2]; 58 node() {} 59 void init() 60 { 61 memset(v, 0, sizeof v); 62 memset(lazy, 0, sizeof lazy); 63 } 64 node operator + (const node &other) const 65 { 66 node res; res.init(); 67 for (int i = 0; i < 2; ++i) res.v[i] = v[i] + other.v[i]; 68 return res; 69 } 70 }a[N << 2], res; 71 void build(int id, int l, int r) 72 { 73 a[id].init(); 74 if (l == r) 75 { 76 a[id].v[0] = deep[fp[l]]; 77 return; 78 } 79 int mid = (l + r) >> 1; 80 build(id << 1, l, mid); 81 build(id << 1 | 1, mid + 1, r); 82 } 83 void pushdown(int id) 84 { 85 for (int i = 0; i < 2; ++i) if (a[id].lazy[i]) 86 { 87 int lazy = a[id].lazy[i]; 88 a[id].lazy[i] = 0; 89 a[id << 1].v[i] += lazy; 90 a[id << 1 | 1].v[i] += lazy; 91 a[id << 1].lazy[i] += lazy; 92 a[id << 1 | 1].lazy[i] += lazy; 93 } 94 } 95 void update(int id, int l, int r, int ql, int qr, int v, int vis) 96 { 97 if (l >= ql && r <= qr) 98 { 99 a[id].v[vis] += v; 100 a[id].lazy[vis] += v; 101 return; 102 } 103 int mid = (l + r) >> 1; 104 pushdown(id); 105 if (ql <= mid) update(id << 1, l, mid, ql, qr, v, vis); 106 if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, v, vis); 107 } 108 void query(int id, int l, int r, int pos) 109 { 110 if (l == r) 111 { 112 res = a[id]; 113 return; 114 } 115 int mid = (l + r) >> 1; 116 pushdown(id); 117 if (pos <= mid) query(id << 1, l, mid, pos); 118 else query(id << 1 | 1, mid + 1,r , pos); 119 } 120 } 121 122 ll qmod(ll base, ll n) 123 { 124 ll res = 1; 125 while (n) 126 { 127 if (n & 1) res = (res * base) % MOD; 128 base = base * base % MOD; 129 n >>= 1; 130 } 131 return res; 132 } 133 ll ans[N]; 134 135 int main() 136 { 137 while (scanf("%d%d", &n, &m) != EOF) 138 { 139 ++n; 140 for (int i = 1; i <= n; ++i) G[i].clear(); 141 memset(fa, 0, sizeof fa); 142 memset(son, 0, sizeof son); cnt = 0; 143 for (int i = 1; i <= m; ++i) q[i].scan(); 144 for (int i = 2; i <= n; ++i) if (!fa[i]) 145 { 146 fa[i] = 1; 147 G[1].push_back(i); 148 } 149 deep[1] = -1; 150 DFS(1); getpos(1, 1); 151 SEG::build(1, 1, n); 152 for (int i = 2; i <= n; ++i) if (fa[i] != 1) 153 SEG::update(1, 1, n, lp[fa[i]], lp[i] - 1, 1, 1); 154 for (int i = m; i >= 1; --i) 155 { 156 if (q[i].op == 2) 157 { 158 SEG::res.init(); 159 SEG::query(1, 1, n, lp[q[i].x]); 160 int x = SEG::res.v[0], y = SEG::res.v[1]; 161 ans[i] = qmod(3, n - x - y - 1) * qmod(2, y) % MOD; 162 } 163 else 164 { 165 SEG::res.init(); 166 SEG::query(1, 1, n, lp[q[i].y]); 167 int x = SEG::res.v[0]; 168 SEG::update(1, 1, n, lp[q[i].y], rp[q[i].y], -x, 0); 169 SEG::update(1, 1, n, lp[q[i].x], lp[q[i].y] - 1, -1, 1); 170 } 171 } 172 for (int i = 1; i <= m; ++i) if (q[i].op == 2) printf("%lld\n", ans[i]); 173 } 174 return 0; 175 }