D. Data Structure Master and Orz Pandas
树上期望dp
列个式子跑一遍树形dp就做完了
场上剩半小时才开这题 没写出来亏死

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7, md = 998244353;
#define ll long long
ll ksm(ll a, ll b) {a %= md;ll res = 1;while (b) {if (b & 1) {res = res * a % md;}a = a * a % md;b >>= 1;}return res % md;
}
ll inv[maxn], siz[maxn], f[maxn];
vector<int> adj[maxn];
void dfs(int u) {siz[u] = 1;for (int i = 0; i < adj[u].size(); i++) {int v = adj[u][i];dfs(v);siz[u] += siz[v];}for (int i = 0; i < adj[u].size(); i++) {int v = adj[u][i];f[u] = (f[u] + siz[v] * inv[siz[u]] % md * (f[v] + (siz[u] - siz[v] - 1) * inv[siz[u]-1] % md) % md ) % md; }
}
int rd() {int s = 0, f = 1; char c = getchar();while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}return s * f;
}
int n;
int main() {n = rd();for (int i = 1; i <= n; i++) {inv[i] = ksm(i, md - 2);}for (int i = 2; i <= n; i++) {adj[rd()].push_back(i);}dfs(1);printf("%lld\n", f[1] % md);//printf("%lld\n", 4ll*inv[7] % md);return 0;
}

G. Gery’s Problem and Orz Pandas
只会O(nlogn)处理每次询问 大力讨论然后加答案
然而这种树上题 答案为和式形式的通常是可以化简式子然后快速统计答案的 比如某经典最短路板子题
正解如下
本题要对每个询问的点对(u,v)(u,v)(u,v) 求出∑r=1ndis(u,lcar(u,v))∗dis(v,lcar(u,v))\sum_{r=1}^{n} dis(u,lca_r(u,v)) *dis(v,lca_r(u,v))r=1∑n​dis(u,lcar​(u,v))∗dis(v,lcar​(u,v))
换根复杂度爆炸
所以我们直接在根为1的树上计算最后答案
注意到当r为lca1(u,v)lca_1(u,v)lca1​(u,v)所在子树外的点时,lcar(u,v)lca_r(u,v)lcar​(u,v)等于lca1(u,v)lca_1(u,v)lca1​(u,v)
否则 lcar(u,v)lca_r(u,v)lcar​(u,v)为u到v路径上的点
并且无论根为哪个点 树上两点间的路径是唯一的
那么我们把路径分成向上的两段来统计答案
拿路径u到lca(u,v)来说
记u为v0v_0v0​ 则路径可表示为v0,v1,...,vqv_0,v_1,...,v_qv0​,v1​,...,vq​
其中fa(vi−1)=vifa(v_{i-1})=v_ifa(vi−1​)=vi​
那么路径上的点对答案的贡献可以表示为∑i=1q(siz[vi]−siz[vi−1])×i×(q−i+dep[v]−dep[lca])\sum_{i=1}^{q}(siz[v_i]-siz[v_{i-1}]) \times i \times(q-i+dep[v]-dep[lca])i=1∑q​(siz[vi​]−siz[vi−1​])×i×(q−i+dep[v]−dep[lca])
siz[vi]−siz[vi−1]siz[v_i]-siz[v_{i-1}]siz[vi​]−siz[vi−1​]表示的是以viv_ivi​为根的子树内的点作为r时,满足lcar(u,v)==vilca_r(u,v)==v_ilcar​(u,v)==vi​的点数
化简式子 我们发现iii可以表示为dep[u]−dep[vi]dep[u]-dep[v_i]dep[u]−dep[vi​]
那么上式一部分改写为∑i=1q(siz[vi]−siz[vi−1])×(dep[u]−dep[vi])×(q−dep[u]+dep[vi])\sum _ {i=1}^{q} (siz[v_i]-siz[v_{i-1}])\times (dep[u]-dep[v_i]) \times(q- dep[u]+dep[v_i])i=1∑q​(siz[vi​]−siz[vi−1​])×(dep[u]−dep[vi​])×(q−dep[u]+dep[vi​]) 另外一部分系数为dep[v]−dep[lca]dep[v]-dep[lca]dep[v]−dep[lca]的类似
展开以后可以把与i无关的全部提取出来
dep[u]×(q−dep[u])×∑i=1q(siz[vi]−siz[vi−1])dep[u]\times (q-dep[u])\times\sum_{i=1}^q (siz[v_i]-siz[v_{i-1}])dep[u]×(q−dep[u])×i=1∑q​(siz[vi​]−siz[vi−1​]) +dep[u]×∑i=1q(siz[vi]−siz[vi−1])×dep[vi]+dep[u]\times\sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])\times dep[v_i] +dep[u]×i=1∑q​(siz[vi​]−siz[vi−1​])×dep[vi​]
−(q−dep[u])×∑i=1q(siz[vi]−siz[vi−1])×dep[vi]-(q-dep[u])\times \sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])\times dep[v_i]−(q−dep[u])×i=1∑q​(siz[vi​]−siz[vi−1​])×dep[vi​]
−∑i=1q(siz[vi]−siz[vi−1])×dep[vi]2-\sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])\times dep[v_i]^2−i=1∑q​(siz[vi​]−siz[vi−1​])×dep[vi​]2

和式∑i=1q(siz[vi]−siz[vi−1])=siz[vq]−siz[v0]\sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])=siz[v_q]-siz[v_0]∑i=1q​(siz[vi​]−siz[vi−1​])=siz[vq​]−siz[v0​]
和式∑i=1q(siz[vi]−siz[vi−1])×dep[vi]\sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])\times dep[v_i]∑i=1q​(siz[vi​]−siz[vi−1​])×dep[vi​]以及∑i=1q(siz[vi]−siz[vi−1])×dep[vi]2\sum_{i=1}^q(siz[v_i]-siz[v_{i-1}])\times dep[v_i]^2∑i=1q​(siz[vi​]−siz[vi−1​])×dep[vi​]2可以树上前缀和预处理一下
lca(u,v)lca(u,v)lca(u,v)的贡献需要特判

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7, md = 998244353;
#define ll long long
vector<int> adj[maxn];
ll s1[maxn], s2[maxn];
ll n, m, dfl[maxn], dep[maxn], siz[maxn], top[maxn], tot, fa[maxn], son[maxn];
int rd() {int s = 0; char c = getchar();while (c < '0' || c > '9') {c = getchar();}while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}return s;
}
void dfs1(int u) {siz[u] = 1;for (int i = 0; i < adj[u].size(); i++) {int v = adj[u][i];if (siz[v]) continue;dep[v] = dep[u] + 1;fa[v] = u;dfs1(v);siz[u] += siz[v];if (siz[v] > siz[son[u]]) son[u] = v;}
}
void dfs2(int u, int t) {dfl[u] = ++tot; top[u] = t;s1[u] = (s1[fa[u]] + (siz[fa[u]] - siz[u]) * dep[fa[u]] % md) % md;s2[u] = (s2[fa[u]] + dep[fa[u]] * dep[fa[u]] % md * (siz[fa[u]] - siz[u]) % md) % md;if (son[u]) {dfs2(son[u], t);}for (int i = 0; i < adj[u].size(); i++) {int v = adj[u][i];if (v != son[u] && dep[v] == dep[u]+1) {dfs2(v, v); }}
}
int getlca(int u, int v) {while (top[u] ^ top[v]) {if (dep[top[u]] < dep[top[v]]) swap(u, v);u = fa[top[u]];}if (dep[u] < dep[v]) return u;return v;
}
int getson(int u, int v) { //求u到v路径上v的儿子int res = 0; //u == v 返回0while (top[u] ^ top[v]) {if(dep[top[u]]<dep[top[v]]) swap(u,v);res = top[u]; u = fa[top[u]];}if (u == v) return res; if (dep[u] < dep[v]) return son[u];else return son[v];
}
int main() {n = rd(), m = rd();for (int i = 1; i < n; i++) {int u = rd(), v = rd();adj[u].push_back(v); adj[v].push_back(u);}dfs1(1); dfs2(1,1);for (int i = 1; i <= m; i++) {int u = rd(), v = rd();int lca = getlca(u, v);ll ans1 = 0, ans2 = 0, ans0 = 0, q = dep[u]-dep[lca];ans0 = ((dep[u]*(q-dep[u])%md*(siz[lca]-siz[u])%md+(2ll*dep[u]-q)*(s1[u]-s1[lca])%md+md-s2[u]+s2[lca])%md+md)%md;ans0 = (ans0 + dep[u]*(dep[v]-dep[lca])%md*(siz[lca]-siz[u])%md-(dep[v]-dep[lca])*(s1[u]-s1[lca])%md+md)%md;ans1 = (-siz[getson(v,lca)]*q%md*(dep[v]-dep[lca])%md+md + ans0)%md;swap(u, v); q = dep[u] - dep[lca];ans0 = ((dep[u]*(q-dep[u])%md*(siz[lca]-siz[u])%md+(2ll*dep[u]-q)*(s1[u]-s1[lca])%md+md-s2[u]+s2[lca])%md+md)%md;ans0 = (ans0 + dep[u]*(dep[v]-dep[lca])%md*(siz[lca]-siz[u])%md-(dep[v]-dep[lca])*(s1[u]-s1[lca])%md+md)%md;ans2 = (-siz[getson(v,lca)]*q%md*(dep[v]-dep[lca])%md+md + ans0)%md;ans0 = (ans1 + ans2 + (siz[1]-siz[lca])*(dep[u]-dep[lca])%md*(dep[v]-dep[lca])%md);ans0 = (ans0 - (siz[lca] - siz[getson(u,lca)] - siz[getson(v,lca)]) * (dep[u]-dep[lca]) % md * (dep[v] - dep[lca]) % md + md) % md;printf("%lld\n", ans0);}
}

E. Encryption of Orz Pandas
异或相当于每一位上进行一次模2意义的前缀和
每次前缀和相当于卷一个系数全为1的多项式
那么k次前缀和要卷的多项式的生成函数就是(1+x+x2+...+xn)k=(11−x)k(1+x+x^2+...+x^n)^k=(\frac{1}{1-x})^k(1+x+x2+...+xn)k=(1−x1​)k
要求第t项的系数 就泰勒展开到第t项
(ddx)t(1−x)−k=k×(k+1)×(k+2)×...×(k+t−1)(1−x)−k−t(\frac{d}{dx})^t(1-x)^{-k}=k\times(k+1)\times(k+2)\times...\times(k+t-1)(1-x)^{-k-t}(dxd​)t(1−x)−k=k×(k+1)×(k+2)×...×(k+t−1)(1−x)−k−t
则(1−x)−k=∑t=0∞Ck+t−1txt(1-x)^{-k}=\sum_{t=0}^{∞}C_{k+t-1}^t x^t(1−x)−k=t=0∑∞​Ck+t−1t​xt
第ttt项的系数就是Ck+t−1tC_{k+t-1}^{t}Ck+t−1t​
在模2意义下 我们判断(k+t)!,k!,t!(k+t)!,k!,t!(k+t)!,k!,t!的质因数分解中2的个数来判断最后模2结果是0还是1
然后fft算一下卷积就行了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 4e5+7;
const double PI = acos(-1.0);
int Bit, Lim;
ll n, k;
struct Complex{double x, y;Complex() {x = y = 0;}Complex(double _x, double _y) {x = _x, y = _y;}
}a[20][maxn], b[maxn];
Complex operator + (Complex a, Complex b) { return (Complex){a.x + b.x, a.y + b.y};}
Complex operator - (Complex a, Complex b) { return (Complex){a.x - b.x, a.y - b.y};}
Complex operator * (Complex a, Complex b) { return (Complex){a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x};}
Complex conj(Complex a) {return (Complex){a.x, -a.y};}      //共轭复数
/*
from: miskcoo's blog
假设 reverse(i) 是将二进制位反转的操作,DFT 最后一步的数组是 B,原来的数组是 A,那么 A 和 B 之间有这样的关系 B[reverse(i)]=A[i],也就是说, B[i + 1]=A[reverse(reverse(i) + 1)],B 中第 i 项的下一项就是将 i 反转后加 1 再反转回来 A 中的那一项,所以现在要模拟的就是从高位开始的二进制加法
反向二进制加法从最高位开始 找到第一个0 然后把这个0改成1 前面的1全部改成0
int reverse_add(int x){for (int l = 1 << bit_length; (x ^= l) < l; l >>= 1);   //如果x的当前位是0 异或后会变大 即退出return x;
}
*/
ll ans[maxn], cntk, cntt[maxn], cnttk[maxn];
ll rd(){ll s = 0, f = 1; char c = getchar();while (c > '9' || c < '0') {if (c == '-') f = -1; c = getchar();}while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();}return s * f;
}
void fft(Complex *a, int n, int f) {   //若要进行逆变换 fft之后结果除以nfor(int i = 0, j = 0; i < n; i++) {//当前下标i 反向下标jif (i > j) swap(a[i], a[j]);    //仅交换一次 因为只有一个对应for (int l = n >> 1; (j ^= l) < l; l >>= 1);    //此时n为2的次幂}for (int i = 2; i <= n; i <<= 1) {//区间长度从小到大int m = i >> 1;   //Complex wn = (Complex) { cos(2 * PI / i), sin(2 * PI * f / i)};for (int k = 0; k < n; k += i) {//每个迭代的区间起点Complex t, w, u;w = (Complex) {1, 0};for (int j = 0; j < m; j++) {//m:半个区间t = w * a[j + m + k];u = a[k + j];a[k + j] = u + t;a[k + j + m] = u - t;w = w * wn;}}}
}
int main() {n = rd(), k = rd();for (ll i = 1; i <= n; i++) {int x = rd();for (int j = 0; j < 17; j++) {a[j][i].x = (x>>j)&1;}}Lim = 1, Bit = 0;while (Lim < n + n + 1) Lim <<= 1, Bit++;for (ll i = 2; i <= k-1ll; i <<= 1) cntk += (k-1ll)/i;for (ll i = 0; i <= n; i++) {for (ll j = 2; j <= n + k; j <<= 1ll) {cntt[i] += i / j;cnttk[i] += (i + k-1ll) / j;}}for (ll i = 0; i <= n; i++) {if (cntt[i] + cntk >= cnttk[i]) b[i].x = 1;else b[i].x = 0;}fft(b, Lim, 1);for (int j = 0; j < 17; j++) {fft(a[j], Lim, 1);for (int i = 0; i <= Lim; i++) {a[j][i] = a[j][i] * b[i];}fft(a[j], Lim, -1);for (int i = 0; i <= n; i++)  {a[j][i].x = (int)(a[j][i].x / Lim + 0.5);ans[i] += (1ll << j) * ((int)a[j][i].x%2);}}for (int i = 1; i <= n; i++) printf("%lld ", ans[i]);
}

Gym102870 2020-2021 “Orz Panda” Cup Programming Contest 补题记录相关推荐

  1. The 2020 ICPC Asia Shenyang Regional Programming Contest I题 Rise of Shadows(数论)

    题目链接The 2020 ICPC Asia Shenyang Regional Programming Contest 题目大意: 一天内有H小时,每小时M分钟,时针分针以恒定速率旋转. 现在若时针 ...

  2. The 14th Chinese Northeast Collegiate Programming Contest 补题

    题目链接 https://codeforces.com/gym/102801 参考题解 B - Team 简要题意: 给定 nnn 和 MMM,有三个组 ABCABCABC,每组 nnn 个人,每人都 ...

  3. The 2020 ICPC Asia Yinchuan Regional Programming Contest

    The 2020 ICPC Asia Yinchuan Regional Programming Contest A 开三个vector数组存储x,y,z轴上的点,unique+erase去重 #in ...

  4. [SWPUCTF] 2021新生赛之Crypto篇刷题记录(11)

    [SWPUCTF] 2021新生赛之Crypto篇刷题记录① [SWPUCTF 2021 新生赛]crypto6 [SWPUCTF 2021 新生赛]ez_caesar [SWPUCTF 2021 新 ...

  5. 2020牛客国庆集训派对day2 补题J

    2020牛客国庆集训派对day2 补题J:VIRUS OUTBREAK 题目描述 The State Veterinary Services Department recently reported ...

  6. The 2020 ICPC Asia Yinchuan Regional Programming Contest 银川 B. The Great Wall 题解

    题目链接:Problem - B - Codeforces input1: 5 1 2 3 4 5 output1: 4 3 2 1 0 input2: 5 1 2 1 2 1 output2: 1 ...

  7. The 2021 Sichuan Provincial Collegiate Programming Contest

    今年年初就和深爷策划去打星参加一场ICPC,正好今年5月底公司多送了2天年假,于是找来了还在电科读研的师弟林喵喵,组了一支退役旅游队.chenjb的这套题出得蛮好,总体来说题目难度不大,但很多题目却很 ...

  8. UCF Local Programming Contest Round 1A记录

    A. Briefcases Full of Money 题目描述 输入描述: 输出描述: 示例1 输入 84 111 2 3 2 3 输出 5 示例2 输入 200 3 20 5 4 1 输出 50 ...

  9. The 2018 JUST Collegiate Programming Contest H题 Cube

    小学数学题 #include<cstdio> #include<cmath> using namespace std; unsigned long long area, ans ...

最新文章

  1. 云计算设计模式(十)——守门员模式
  2. Softmax和Cross-entropy是什么关系?
  3. Android实现模块 api 化
  4. FFmpeg滤镜使用指南
  5. flask+redis实现抢购(秒杀)功能
  6. UICollectionView reloadData后cell被隐藏
  7. elementui树状菜单tree_vue.js+element-ui做出菜单树形结构
  8. Leetcode--213. 打家劫舍Ⅱ
  9. SPA 单页Web应用
  10. 小知识—PRINCE2的七大原则之剪裁
  11. Apache MiNa 实现多人聊天室
  12. 数据库,规则库和知识库的比较
  13. 微软原版Windows 8 原版镜像
  14. PR常用的效果和转场,视频防抖、宽银幕效果、设置默认效果
  15. VP9编码(3)-- 符号
  16. linux下postgresql创表添加数据
  17. 崛起的云平台,彰显信息国产化的中国力量
  18. 计算机组成原理复习要点与考题类型--选择-填空-分析-计算-简答
  19. 花样16流水灯c语言程序,8个花样流水灯c程序
  20. 19_多易教育之《yiee数据运营系统》用户画像-算法导论篇

热门文章

  1. 【windows】TeamViewer软件连接不上网络
  2. C51简易计算器微机课设
  3. 微信小程序蓝牙BLE开发实战——案例(二)
  4. 成功解决[Error] reference to ‘xx’ is ambiguous
  5. mw325r 服务器无响应),水星(MERCURY)MW325R路由器上不了网/连不上网怎么办?
  6. Threejs—BIM管道流向动态效果
  7. 合肥-NIO蔚来汽车JAVA开发
  8. pandas计算最大回撤
  9. Android 四大组件之 Service_5_拦截电话号码
  10. 王传福和比亚迪“造富神话”