Replay


Dup4:

  • 厕所是个换换脑子的好地方?
  • 要读题啊,不要别人不做,自己就跟着不做啊

X:

  • 读题很重要啊!什么时候才能读对题 不演队友啊 D题看错题, 直到最后一小时才看懂
  • 很多时候要看榜单做题

A:Aqours

Solved.

考虑一个点的子树下面有多少个叶子节点汇聚,

那么这个时候就可以更新某些叶子节点的答案

并且把距离该点最近的叶子节点返回上去继续做这一步操作

再正着  考虑除子树外 的离当前点最近的叶子节点的距离,用于更新子树中叶子结点的答案

相当于树形dp起手式

但是这里$n很大,不能DFS$

但是又注意到$i <= j  有 fa[i] < fa[j]$

相当于$bfs序列是1\;2\;\cdots n$

可以直接两次遍历来做这件事情

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 3000010
 5 #define pii pair <int, int>
 6 int n, fa[N], ans[N], d[N];
 7 vector <pii> G[N];
 8 pii g[N];
 9
10 int main()
11 {
12     while (scanf("%d", &n) != EOF)
13     {
14         for (int i = 1; i <= n; ++i) G[i].clear();
15         memset(ans, -1, sizeof ans);
16         memset(d, 0, sizeof d);
17         fa[1] = 0;
18         for (int i = 2; i <= n; ++i)
19         {
20             scanf("%d", fa + i);
21             ++d[fa[i]];
22         }
23         for (int v = n; v >= 1; --v)
24         {
25             int u = fa[v];
26             if (!d[v])
27                 G[u].push_back(pii(v, 1));
28             else
29             {
30                 sort(G[v].begin(), G[v].end());
31                 pii tmp = *G[v].begin();
32                 ++tmp.second;
33                 G[u].push_back(tmp);
34                 int Min = (*G[v].begin()).second;
35                 for (int i = 1, len = G[v].size(); i < len; ++i)
36                 {
37                     pii it = G[v][i];
38                     ans[it.first] = Min + it.second;
39                 }
40             }
41         }
42         for (int v = 1; v <= n; ++v)
43         {
44             g[v] = pii(1e9, 1e9);
45             int u = fa[v];
46             if (u)
47             {
48                 g[v] = g[u];
49                 ++g[v].second;
50                 pii tmp = g[v];
51                 if (tmp.first != -1) for (int i = 0, len = G[v].size(); i < len; ++i)
52                 {
53                     pii it = G[v][i];
54                     if (it.first > tmp.first)
55                         ans[it.first] = min(ans[it.first], it.second + tmp.second);
56                 }
57             }
58             if (!G[v].empty())
59             {
60                 pii it = *G[v].begin();
61                 if (it.second < g[v].second)
62                     g[v] = it;
63             }
64         }
65         for (int i = 1; i <= n; ++i) if (!d[i]) printf("%d %d\n", i, ans[i]);
66     }
67     return 0;
68 }

View Code

B:玖凛两开花

Upsolved.

我们可以发现,如果答案是$x,那么小于等于x的点的都要匹配到大于等于x的点$

那么我们把$小于x的点放在左边,大于等于x的点放在右边,二分匹配即可$

这样就有一个二分的做法

但实际上一步一步枚举上去也是可行的,$枚举到x + 1的时候,拆掉x + 1原有的匹配关系,再匹配一次即可$

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 10010
 5 int n, m, l, r;
 6 vector <int> G[N];
 7
 8 int linker[N];
 9 bool used[N];
10 bool DFS(int u)
11 {
12     for (auto v : G[u]) if (v >= l && v <= r && !used[v])
13     {
14         used[v] = true;
15         if (linker[v] == -1 || DFS(linker[v]))
16         {
17             linker[v] = u;
18             return true;
19         }
20     }
21     return false;
22 }
23
24 int main()
25 {
26     while (scanf("%d%d", &n, &m) != EOF)
27     {
28         for (int i = 1; i <= n; ++i) G[i].clear();
29         for (int i = 1, u, v; i <= m; ++i)
30         {
31             scanf("%d%d", &u, &v);
32             G[u].push_back(v);
33             G[v].push_back(u);
34         }
35         int res = 0;
36         memset(linker, -1, sizeof linker);
37         for (int i = 0; i < n - 1; ++i)
38         {
39             l = i + 1, r = n - 1;
40             if (linker[i] != -1)
41             {
42                 memset(used, 0, sizeof used);
43                 if (!DFS(linker[i])) break;
44                 linker[i] = -1;
45             }
46             memset(used, 0, sizeof used);
47             if (DFS(i)) ++res;
48             else break;
49         }
50         printf("%d\n", res);
51     }
52     return 0;
53 }

View Code

D:吉良吉影的奇妙计划

Solved.

n只有20

暴力打表

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef long long ll;
 6 const int maxn = 110;
 7 const ll MOD = 998244353;
 8
 9
10 int n;
11 ll ans = 0;
12 int arr[maxn];
13 int tmp[maxn];
14
15 bool judge()
16 {
17     for(int i = 1; i <= 2 * n; ++i) tmp[i] = arr[i];
18     int flag = 1;
19     while(flag)
20     {
21         flag = 0;
22         for(int i = 1; i + 1 <= 2 * n; ++i)
23         {
24             if((tmp[i] == 1 && tmp[i + 1] == 0) || (tmp[i] == 0 && tmp[i + 1] == 1))
25             {
26                 tmp[i] = tmp[i + 1] = -1;
27                 flag = 1;
28                 break;
29             }
30         }
31     }
32     for(int i = 1; i + 3 <= 2 * n; ++i)
33     {
34         if(tmp[i] + tmp[i + 1] + tmp[i + 2] + tmp[i + 3] == -4) return true;
35     }
36     return false;
37 }
38
39 void DFS(int cnt, int cnt1, int cnt0)
40 {
41     if(cnt == 2 * n + 1)
42     {
43         ans = (ans + 1) % MOD;
44         return ;
45     }
46     if(cnt1)
47     {
48         if(cnt == 1 || (cnt > 1 && arr[cnt - 1] != 0))
49         {
50             arr[cnt] = 1;
51             DFS(cnt + 1, cnt1 - 1, cnt0);
52         }
53     }
54     if(cnt0)
55     {
56         if(cnt == 1 || (cnt > 1 && arr[cnt - 1] != 1))
57         {
58             arr[cnt] = 0;
59             DFS(cnt + 1, cnt1, cnt0 - 1);
60         }
61     }
62     if(cnt1 > 0 && cnt0 > 0)
63     {
64         if((cnt + 1 <= 2 * n && arr[cnt - 1] != -1))
65         {
66             arr[cnt] = -1;
67             arr[cnt + 1] = -1;
68             DFS(cnt + 2, cnt1 - 1, cnt0 - 1);
69             arr[cnt] = -2;
70             arr[cnt + 1] = -2;
71         }
72     }
73 }
74
75 int main()
76 {
77     while(~scanf("%d", &n))
78     {
79         ans = 0;
80         DFS(1, n, n);
81         cout << ans << endl;
82     }
83     return 0;
84 }

View Code

E:Souls-like Game

Solved.

阅读理解题

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define ll long long
 5 #define N 10010
 6 const ll MOD = (ll)998244353;
 7 int n, m, p[N][3][3];
 8
 9 int main()
10 {
11     while (scanf("%d%d", &n, &m) != EOF)
12     {
13         for (int i = 1; i < n; ++i)
14         {
15             for (int j = 0; j < 3; ++j)
16                 for (int k = 0; k < 3; ++k)
17                     scanf("%d", &p[i][j][k]), p[i][j][k] %= MOD;
18         }
19         for (int i = 1, op, l, r; i <= m; ++i)
20         {
21             scanf("%d%d%d", &op, &l, &r);
22             if (op == 1)
23             {
24                 int pp[3][3];
25                 for (int j = 0; j < 3; ++j)
26                     for (int k = 0; k < 3; ++k)
27                         scanf("%d", &pp[j][k]), pp[j][k] %= MOD;
28                 for (int j = l; j <= r; ++j)
29                     for (int k = 0; k < 3; ++k)
30                         for (int o = 0; o < 3; ++o)
31                             p[j][k][o] = pp[k][o];
32             }
33             else
34             {
35                 ll sum[2][3] = {0, 0, 0};
36                 for (int j = 0; j < 3; ++j) sum[r & 1][j] = 1;
37                 for (int j = r - 1; j >= l; --j)
38                 {
39                     for (int k = 0; k < 3; ++k) sum[j & 1][k] = 0;
40                     for (int k = 0; k < 3; ++k)
41                         for (int o = 0; o < 3; ++o)
42                             sum[j & 1][k] = (sum[j & 1][k] + p[j][k][o] * sum[(j & 1) ^ 1][o] % MOD) % MOD;
43                 }
44                 ll res = 0;
45                 for (int j = 0; j < 3; ++j)
46                     res = (res + sum[l & 1][j]) % MOD;
47                 //for (int j = 0; j < 3; ++j) printf("%lld%c", sum[l & 1][j], " \n"[j == 2]);
48                 printf("%lld\n", res);
49             }
50         }
51     }
52     return 0;
53 }

View Code

G:穗乃果的考试

Solved.

$考虑到每个(i, j)位置上的1可能被i \cdot (n - i + 1) \cdot j \cdot (m - j + 1)的矩形包含$

$即每个1都会产生i \cdot (n - i + 1) \cdot j \cdot (m - j + 1)的贡献 累加即可$

 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 = 2e3 + 10;
 9
10 int n, m;
11 char mp[maxn][maxn];
12
13 int main()
14 {
15     while(~scanf("%d %d", &n, &m))
16     {
17         ll ans = 0;
18         for(int i = 1; i <= n; ++i)
19         {
20             for(int j = 1; j <= m; ++j)
21             {
22                 scanf(" %c", &mp[i][j]);
23                 if(mp[i][j] == '1')
24                 {
25                     ll tmp = i * (n - i + 1) % MOD * j % MOD * (m - j + 1) % MOD;
26                     ans = (ans + tmp) % MOD;
27                 }
28             }
29         }
30         printf("%lld\n", ans);
31     }
32     return 0;
33 }

View Code

I:岸边露伴的人生经验

Upsolved.

将十维的向量拆成二十位的二进制数

可以通过FWT快速的卷积以下,得到异或后相同的对数

为了方便,我们将距离平方

再将异或值转换成距离

这里注意$dis(1, 2) = 1, 而 1 \oplus 2 = 3$

$dis(0, 2) = 4, 0 \oplus 2 = 2$

然后统计即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define ll long long
 5 #define N 2500010
 6 const ll MOD = (ll)998244353;
 7 const ll inv_2 = (ll)499122177;
 8 int n;
 9 ll c[N];
10 ll a[110];
11
12 void FWT(ll x[],int len,int mode)
13 {
14     for(int i=2;i<=len;i<<=1)
15     {
16         int step=i>>1;
17         for(int j=0;j<len;j+=i)
18             for(int k=j;k<j+step;k++)
19             {
20                 ll a=x[k],b=x[k+step];
21                 x[k]=(a+b)%MOD;
22                 x[k+step]=(a-b+MOD)%MOD;
23                 if(mode==-1) (x[k] *= inv_2)%=MOD,(x[k+step]*=inv_2)%=MOD;
24             }
25     }
26 }
27
28 int get(int x)
29 {
30     int res = 0;
31     for (int i = 19; i >= 0; i -= 2)
32     {
33         int a = (x >> i) & 1, b = (x >> (i - 1)) & 1;
34         if (a == 1 && b == 0) res += 4;
35         else if (a == 1 && b == 1) res += 1;
36         else res += (a << 1) + b;
37     }
38     return res;
39 }
40
41 int main()
42 {
43     while (scanf("%d", &n) != EOF)
44     {
45         memset(c, 0, sizeof c);
46         memset(a, 0, sizeof a);
47         for (int i = 1, x; i <= n; ++i)
48         {
49             int tmp = 0;
50             for (int j = 1; j <= 10; ++j)
51             {
52                 scanf("%d", &x);
53                 if (x == 0) tmp <<= 2;
54                 else if (x == 1) tmp <<= 2, tmp += 1;
55                 else if (x == 2) tmp <<= 1, tmp += 1, tmp <<= 1;
56             }
57             ++c[tmp];
58         }
59         FWT(c, 1 << 20, 1);
60         for (int i = 0; i <= 1 << 20; ++i) c[i] = (c[i] * c[i]) % MOD;
61         FWT(c, 1 << 20, -1);
62         for (int i = 0; i <= 1 << 20; ++i)
63             a[get(i)] += c[i];
64         ll res = 0;
65         for (int i = 0; i <= 40; ++i) res = (res + a[i] * a[i] % MOD) % MOD;
66         printf("%lld\n", res);
67     }
68     return 0;
69 }

View Code

转载于:https://www.cnblogs.com/Dup4/p/10327868.html

CCPC-Wannafly Winter Camp Day8 (Div2, onsite)相关推荐

  1. 2019 CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题记录

    一篇来自ACM入门者的补题记录 最近有点懒,想着还有最后一篇博客没完成,是我最大的补题动力. 不过终于在camp过去三个月的时候完成了所有的补题博客,有点欣慰,下一个目标应该是补一补一年前暑期训练的题 ...

  2. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) A 题 Aqours (精巧的树形DP)

    题目链接: https://www.cometoj.com/contest/29/problem/A?problem_id=414 Aqours 题目描述 Aqours 正在 LoveLive! 决赛 ...

  3. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题

    A Aqours 题解: https://www.cnblogs.com/qieqiemin/p/11251645.html D:吉良吉影的奇妙计划 (暴力打表) 题目描述 吉良吉影是一个平凡的上班族 ...

  4. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 去音乐会

    题目链接 题目描述 在冬马曜子工作室的安排下,和纱会在维也纳休养a天,然后去日本开b-a天音乐会,并以b天为一周期不断循环.而根据Knight Records的工作安排,雪菜会去外地出差c天,然后休息 ...

  5. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)(补题记录)

    一篇来自ACM入门者的补题记录 文章目录 A.机器人 B.吃豆豆 C.拆拆拆数 E.流流流动 F.爬爬爬山 I.起起落落 J.夺宝奇兵 A.机器人 题意:有两条平行线段A,B,长度从1~n,机器人一开 ...

  6. 阔力梯的树(2020 CCPC Wannafly Winter Camp Day2 Div.12 )dsu on tree

    题解: dsu on tree dsu on tree的基本步骤就不说了 看到这题询问结点的子树问题,而且询问时离线的,首先想到的dsu on tree的这个trick. 本题的难题就是如何维护结点所 ...

  7. CCPC-Wannafly Winter Camp Day3 (Div2, onsite) I 石头剪刀布(按秩合并并查集)

    题解:每次有两个事件: y y去挑战xx,如果赢了可以坐在x x的位置,打平或者输了就要被淘汰. 询问在进行所有一类事件后,有多少种情况可以让x x现在还没有被淘汰. 对于第二类事件,我们假设x x挑 ...

  8. 2020 CCPC Wannafly Winter Camp Day3 部分题解(ACEFG)

    查看题目 A 黑色气球 题意: n个气球,每个气球高度为正整数.给你每两个气球之间的高度和,还原出所有气球的高度,保证答案唯一. 解题思路: 签到题,因为高度的范围不大,直接枚举第一个气球的高度,检测 ...

  9. CCPC-Wannafly Winter Camp Day3 (Div2, onsite) F 小清新数论 欧拉函数的利用 莫比乌斯反演 杜教筛

    F - 小清新数论 做法一:欧拉函数 #include<stdio.h> #include<bits/stdc++.h> using namespace std; #defin ...

最新文章

  1. python爬取多页_Python 爬虫 2 爬取多页网页
  2. 【NLP】不讲武德,只用标签名就能做文本分类
  3. 树莓派声音输出设置_树莓派声音设置
  4. 大数据导论章节答案_托福100+需要准备多久?考生大数据给你答案
  5. 个别学生计算机辅导计划,网络学院计算机基础统考辅导计划.doc
  6. java 区块链开发_Java开发人员的区块链入门
  7. 十几减9的口算题_小学一年级下册十几减9数学教案
  8. 洛谷——P1307 [NOIP2011 普及组] 数字反转
  9. c/c++将字符串中的空格替换成%20
  10. category is in invalid format hint微信第三方平台将第三方提交的代码包提交审核出错...
  11. 安卓逆向之某瓜数据app签名sign破解
  12. 用python计算工程量_总算懂了工程造价工程量计算方法
  13. 今日头条如何赚钱,今日头条赚钱规则,今日头条快速赚钱技巧
  14. 如何利用Photoshop进行快速切图
  15. 【乐器常识】声音之美
  16. 盘点!一篇看完2018年中国各地编程教育政策
  17. 【DNS域名解析服务】
  18. MySQL基础~NATURAL JOIN(自然连接) 和USING的使用(SQL99语法新特性)
  19. Mac Docker入门安装使用
  20. python实现多张多格式图片转PDF并打包成exe

热门文章

  1. 每年存1.4万,40年后你将有多少钱?算完惊呆了!
  2. 2021年上半年软件设计师下午真题及答案解析(三)
  3. 史上最通俗易懂 pvalue
  4. win10不能访问samba共享问题的解决
  5. 14.刚体组件Rigidbody
  6. 【C/C++】用格雷戈里公式求π
  7. 2021 年8月份最新数据库排行榜出炉
  8. OPCService发布网址(wincc开放接口)
  9. 【远程文件浏览器】Unity+Lua开发调试利器
  10. 计算机团体及知名科学家,2019年度ACM杰出科学家!拿下华人数学领域最高荣誉的上财陆品燕教授,又拿奖啦!...