color

题意

\(\;\)

给定\(p_1,p_2\),要求\(p_1\)的倍数格子填红色,\(p_2\)的倍数格子填蓝色,既是\(p_1\)又是\(p_2\)倍数的格子颜色任选。求是否存在一种填法,满足忽略掉无色格子后不存在个连续\(k\)相同颜色的格子

\(\;\)

比较水的一道题。

用\(gcd(p_1,p_2)\)和贪心乱搞一通,用裴蜀定理证明,没了。

但是千万千万记得要特判\(k=1\)

时间复杂度:\(O(T\;log\;p)\)

code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. using namespace std;
  6. #define LL long long
  7. LL a, b, k, T;
  8. LL gcd(LL a,LL b)
  9. {
  10. if(b == 0) return a;
  11. return gcd(b , a % b);
  12. }
  13. int main()
  14. {
  15. cin>>T;
  16. while(T--)
  17. {
  18. scanf("%lld%lld%lld",&a,&b,&k);
  19. if(k == 1)
  20. {
  21. puts("No");
  22. continue;
  23. }
  24. if(a > b)swap(a,b);
  25. LL g = gcd(a,b);
  26. LL t = ((b - g) % a == 0) ? 0 : 1;
  27. if((b - g) / a + t < k)puts("Yes");
  28. else puts("No");
  29. }
  30. return 0;
  31. }

\(\;\)

\(\;\)

sequence

\(\;\)

题意

\(\;\)

给一个长度为\(n\)的序列\(A_1,A_2,\cdots,A_n.\;\)定义\(f(l,r)\)为[l,r]中不同的数字个数.求

\(\sum_{l=1}^n \sum_{r=l}^n f(l,r)^2\)

\(\;\)

暴力

\(\;\)

直接枚举\(l,r\),然后在\(r\)不断加\(1\)的同时,更新此时区间中数字种类个数

时间复杂度:\(O(n^2)\)

期望得分:\(50pts\)

\(\;\)

\(\;\)

正解

\(\;\)

直接求平方似乎不太好操作

\(\because f(l,r)^2=f(l,r)(f(l,r)-1)+f(l,r)\)

不妨设\(F(n)=\sum_{i=1}^n f(i,n)\;,\;g(n)=\sum_{i=1}^n f(i,n)(f(i,n)-1)\)

然后我们只需分别求\(\sum_{i=1}^n F(n),g(n)\)即可

关键是怎么求?

\(\;\)

\(\;\)

现在给出一个思路:求\(F(n)-F(n-1)\)与\(g(n)-g(n-1)\)

而\(F(n)\)中的每个区间只比\(F(n-1)\)中的区间多了\(a_n\)

所以我们预处理出\(last_n=j\),\(j<n\)且\(a_j=a_n\)(\(j\)是满足这个条件中最靠后的)

因此只有\([last_n+1,n]\)为\(l\)端点的区间才会多出\(a_r\)这个新的数字,产生\(1\)的贡献,总共多产生了\(n-last_n\)的贡献

\(\therefore F(n)-F(n-1)=n-last_n\)

而这个玩意相当于把\([last_n+1,n]\)这段区间执行\(+1\)的操作

\(\;\)

而求\(g(n)-g(n-1)\)与\(F\)同理。

\([last_n+1,n]\)为\(l\)端点的区间,多产生\(1\)的贡献。

因此:这些区间的\(f(l,r)(f(l,r)-1)=>f(l,r)(f(l,r)+1)\)

\(\because f(l,r)(f(l,r)+1)-f(l,r)(f(l,r)-1)=2\times f(l,r)\)

所以总共会增长:\(2\times \sum_{i=last_n+1}^n f(i,r)\)

而:\(\sum_{i=last_n+1}^n f(i,r)\)实际是一个区间求和的操作

\(\;\)

区间执行\(+1\),区间求和你想到了什么?

没错,就是线段树。

因此在枚举\(r\)(右端点)的过程中用线段树维护区间修改与和。

注意在修改与求和的顺序。

时间复杂度:\(O(n\;log\;n)\)

期望得分:\(100pts\)

code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. using namespace std;
  6. const int N = 1000010, mod = 1000000007;
  7. #define LL long long
  8. #define F(i,a,b) for(int i=a;i<=b;i++)
  9. #define ls(x) x<<1
  10. #define rs(x) x<<1|1
  11. int n, a[N], b[N], ap[N], last[N];
  12. LL tree[N << 2], tag[N << 2], f[N], g[N], res1, res2;
  13. inline void push_up(int root)
  14. {
  15. tree[root] = (tree[ls(root)] + tree[rs(root)]) % mod;
  16. }
  17. void build (int root, int l, int r)
  18. {
  19. if(l==r)
  20. {
  21. return;
  22. }
  23. int mid = (l + r) >> 1;
  24. build(ls(root), l, mid);
  25. build(rs(root), mid+1, r);
  26. push_up(root);
  27. }
  28. inline void change(int root, int l, int r, LL k)
  29. {
  30. tag[root] = (tag[root] + k) % mod;
  31. tree[root] = (tree[root] + (r-l+1) * k % mod) % mod;
  32. }
  33. void push_down(int root, int l, int r)
  34. {
  35. if(tag[root])
  36. {
  37. int mid = (l + r) >> 1;
  38. change(ls(root), l, mid, tag[root]);
  39. change(rs(root), mid+1, r, tag[root]);
  40. }
  41. tag[root] = 0;
  42. }
  43. void Update(int root, int L, int R, int l, int r, LL k)
  44. {
  45. if(l<=L&&R<=r)
  46. {
  47. change(root,L,R,k);
  48. return;
  49. }
  50. push_down(root,L,R);
  51. int mid = (L + R) >> 1;
  52. if(l <= mid) Update(ls(root), L, mid, l, r, k);
  53. if(r > mid) Update(rs(root), mid+1, R, l, r, k);
  54. push_up(root);
  55. }
  56. LL Query(int root, int L, int R, int l, int r)
  57. {
  58. LL res = 0;
  59. if(l<=L&&R<=r)
  60. {
  61. return tree[root];
  62. }
  63. push_down(root,L,R);
  64. int mid = (L + R) >> 1;
  65. if(l <= mid) res = (res + Query(ls(root), L, mid, l, r)) % mod;
  66. if(r > mid) res = (res + Query(rs(root), mid+1, R, l, r)) % mod;
  67. return res;
  68. }
  69. int main()
  70. {
  71. scanf("%d",&n);
  72. F(i,1,n)
  73. {
  74. scanf("%d",&a[i]);
  75. b[i]=a[i];
  76. }
  77. sort(b+1,b+n+1);
  78. int m = unique(b+1,b+n+1) - b - 1;
  79. F(i,1,n)
  80. {
  81. a[i] = lower_bound(b+1,b+m+1,a[i]) - b;
  82. }
  83. F(i,1,n)
  84. {
  85. last[i]=ap[a[i]];
  86. ap[a[i]]=i;
  87. }
  88. build(1,1,n);
  89. F(r,1,n)
  90. {
  91. f[r] = (f[r-1] + r - last[r]) % mod;
  92. res1 = (res1 + f[r]) % mod;
  93. g[r] = (g[r-1] + 2 * Query(1,1,n,last[r]+1,r)) % mod;
  94. res2 = (res2 + g[r]) % mod;
  95. Update(1,1,n,last[r]+1,r,1);
  96. }
  97. printf("%lld",(res1 + res2) % mod);
  98. return 0;
  99. }

\(\;\)

\(\;\)

match

\(\;\)

题意

小 A 和小 B 正在玩一个游戏:有一棵包含 \(n\) 个点的有根树(点从 \(1-n\) 编号),它的根是\(1\) 号点,初始时两人各拥有 \(m\) 个点。游戏的每个回合两人都需要选出一个自己拥有且之前未被选过的点,若对手的点在自己的点的子树内,则该回合自己获胜;若自己的点在对方的点的子树内,该回合自己失败;其他情况视为平局。游戏共进行$ m$ 回合。

作为旁观者的你只想知道,在他们随机选点的情况下,第一次非平局回合出现时的回合数的期望值。

为了计算这个期望,你决定对于\(k=0,1,2,\cdots,m\),计算出非平局回合数为\(k\)的情况数。两种情况不同当且仅当存在一个小 A 拥有的点 \(x\),小 B 在\(x\) 被小 A 选择的那个回合所选择的点不同。

由于情况总数可能很大,你只需要输出答案对\(998244353\)取模后的结果

\(\;\)

\(\;\)

暴力

\(\;\)

枚举所有的可能性,对每种情况处理一下统计一下非平局的个数。

时间复杂度:\(O(m!)\)

期望得分:\(20pts\)

\(\;\)

\(\;\)

正解

\(\;\)

\(\;\)

考虑树上DP

\(\;\)

设\(f_{u,i}\)表示以\(u\)为根的子树中,有\(i\)对互为祖先与后代的关系的方案数。

状态转移?其实与各种树上DP的套路类似,考虑\(u\)与它的若干个子树\(v\)的关系

根据乘法原理,有:\(f_{u,j+k}=f_{u,j}\times f_{v,k}\)

但注意:这里的转移不能直接拿\(f\)数组进行,而应先用一个\(tmp\)数组按上面的方程进行转移,再将其赋给\(f\)数组。

原因是我们要保证转移方程中的\(f_{u,j}\)一定是\(v\)这个子树之前的方案数,并没算\(v\)这棵子树的贡献。而若直接用\(f\)数组进行转移,可能导致这里\(f_{u,j}\)是加上了\(v\)这棵子树的结果。其实与01背包的倒序循环类似

\(\;\)

算u的贡献

\(\;\)

因为\(u\)能与它的子树内所有颜色不同的节点组成一对。所以设\(cnt_{u,0/1}\)表示以\(u\)为根的0/1颜色的个数,设\(color_u\)表示\(u\)的颜色。

则与\(u\)不同颜色的节点有\(cnt_{u,color_u \; xor \; 1}\)个。

因此我们可以得到转移方程:

\(f_{u,i}=f_{u,i-1}\times (cnt_{u,color_u \; xor \; 1} - (i-1))\)

\(\;\)

统计答案

\(\;\)

设\(Ans_i\)表示整棵树中有\(i\)对的方案数。则\(Ans_i=f_{1,i}\times (m-i)!\)。等价于选出那\(i\)对后,剩下的随便组合。

但这样并不正确,剩下的点对也有可能组成祖先与后代的关系。

于是我们发现,这其实是一个类似容斥原理的东西。

对于每个有\(i\)对的方案,在统计的时候,由于剩下的点也有可能组成点对,所以其实可能有\(i+1,i+2,\cdots,m\)个点对。

所以我们要将它们减去。

而对于\(i+1\)个点对的每一种方案,都会被算\(C_{i+1}^i\)次,相当于从这些中挑出\(i\)对。

如此类比可得:对于任意的\(j(j>i)\)要减去\(C_j^i \times Ans_j\) 次。

于是通过这样的操作,即可保证不会算重。

时间复杂度

\(\;\)

乍一看是\(O(n^3)\)。但细细观察即可发现,我们在进行树上DP时,相当于是合并两颗子树中的点,只会在它们的LCA处作一次贡献。

所以是\(O(n^2)\)

期望得分:\(100pts\)

\(\;\)

code

  1. #include <cstdio>
  2. #include <vector>
  3. #include <cstring>
  4. #include <iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int N = 5010, mod = 998244353;
  8. int n, m, f[N][N], g[N], siz[N], cnt[N][2], fac[N], color[N], tmp[N];
  9. int Invfac[N];
  10. char str[N];
  11. vector<int> G[N];
  12. void Dfs(int u,int fa)
  13. {
  14. f[u][0] = 1;
  15. for(int i=0;i<G[u].size();i++)
  16. {
  17. int v = G[u][i];
  18. if(v == fa) continue;
  19. Dfs(v,u);
  20. for(int j=0;j<=siz[u]+siz[v];j++)tmp[j] = 0;
  21. for(int j=0;j<=siz[u];j++)
  22. {
  23. for(int k=0;k<=siz[v];k++)
  24. {
  25. tmp[j + k] = (tmp[j + k] + 1LL * f[u][j] * f[v][k] % mod) % mod;
  26. }
  27. }
  28. for(int j=0;j<=siz[u]+siz[v];j++)f[u][j] = tmp[j];
  29. siz[u] += siz[v];
  30. cnt[u][0] += cnt[v][0]; cnt[u][1] += cnt[v][1];
  31. }
  32. siz[u] ++;
  33. cnt[u][color[u]] ++;
  34. for(int j=siz[u];j;j--)
  35. {
  36. f[u][j] = (f[u][j] + 1LL * f[u][j - 1] * (cnt[u][color[u] ^ 1] - j + 1) % mod) % mod;
  37. }
  38. }
  39. int ksm(int a,int b)
  40. {
  41. int res = 1;
  42. while(b)
  43. {
  44. if(b & 1) res = 1LL * res * a % mod;
  45. a = 1LL * a * a % mod;
  46. b >>= 1;
  47. }
  48. return res;
  49. }
  50. int C(int n,int m)
  51. {
  52. return 1LL * fac[n] * Invfac[n - m] % mod * Invfac[m] % mod;
  53. }
  54. int main()
  55. {
  56. cin >> n >> str + 1;
  57. m = n / 2;
  58. for(int i=1;i<=n;i++)
  59. {
  60. color[i] = (str[i] == '0') ? 0 : 1;
  61. }
  62. for(int i=1;i<n;i++)
  63. {
  64. int u, v;
  65. cin >> u >> v;
  66. G[u].push_back(v); G[v].push_back(u);
  67. }
  68. Dfs(1,0);
  69. fac[0] = 1;
  70. for(int i=1;i<=n;i++)
  71. {
  72. fac[i] = 1LL * fac[i - 1] * i % mod;
  73. }
  74. Invfac[0] = 1;
  75. for(int i=1;i<=n;i++)
  76. {
  77. Invfac[i] = 1LL * Invfac[i - 1] * ksm(i,mod - 2) % mod;
  78. }
  79. for(int i=0;i<=m;i++)
  80. {
  81. g[i] = 1LL * fac[m - i] * f[1][i] % mod;
  82. }
  83. for(int i=m;i>=0;i--)
  84. {
  85. for(int j=i+1;j<=m;j++)
  86. {
  87. g[i] = (g[i] - 1LL * C(j,i) * g[j] % mod + mod) % mod;
  88. }
  89. }
  90. for(int i=0;i<=m;i++)printf("%d\n",g[i]);
  91. return 0;
  92. }

NOI Online #2 赛后题解的更多相关文章

  1. 牛客NOIP暑期七天营-TG1 赛后题解

    目录 牛客NOIP暑期七天营-提高组1 A-最短路 题目描述 link 题解 代码 B-最小生成链 题目描述 link 题解 代码 C-最小字典最短路 题目描述 link 题解 Update 牛客NO ...

  2. NOI 2021 部分题目题解

    最近几天复盘了一下NOI 2021,愈发发觉自己的愚蠢,可惜D2T3仍是不会,于是只写前面的题解 Day1 T1 可以发现,每次相当于将 \(x\to y\) 染上一种全新颜色,然后一条边是重边当且仅 ...

  3. NOI 2011 兔农 题解

    事先声明,本博客代码主要模仿accepoc,且仅针对一般如本博主一样的蒟蒻. 这道题不得不说数据良心,给了75分的水分,但剩下25分真心很难得到,因此我们就来讲一讲这剩下的25分. 首先,有数据可知他 ...

  4. 牛客NOIP暑期七天营-TG3 赛后题解

    目录 牛客NOIP暑期七天营-提高组3 A-破碎的矩阵 题目描述 link 题解 代码 B-点与面 题目描述 link 题解 代码 C-信息传递 题目描述 link 题解 牛客NOIP暑期七天营-提高 ...

  5. NOI Online 提高组 题解

    来补坑了-- 个人认为三道题难度差不多-- 还有要说一嘴,为啥我在其他网站代码都好好的,复制到 cnblogs 上 Tab 就成 8 空格了?不过也懒得改了. T1 序列 首先,遇到这种加一减一还带附 ...

  6. JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解

    其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy 这可是紫题啊 题目大意 给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和 题解 如此 ...

  7. NOI 题库 8471 题解

    8471   切割回文 描述 阿福最近对回文串产生了非常浓厚的兴趣. 如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串.例如,“abcaacba”是一个回文串,“abca ...

  8. NOI 题库 9272 题解

    9272   偶数个数字3 描述 在所有的N位数中,有多少个数中有偶数个数字3? 输入 一行给出数字N,N<=1000 输出 如题 样例输入 2 样例输出 73 Solution : 令f ( ...

  9. 【CYH-02】noip2018数论模拟赛:赛后题解

    1.小奔的矩阵 2.大奔的方案 3.小奔与不等四边形 4.小奔的方案 当然本次比赛肯定难度不会仅限于此啦!后续还会--

随机推荐

  1. MapReduce基本认识

    MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算. 主要由Split.Map.Partition.Sort.Combine(需要自己写).Merge.Reduce组成,一般来 ...

  2. swoole学习--登录模块

    使用swoole+thinkphp6.0+redis 结合开发的登录模块,做完之后有几点感悟: 1.不要相信任务数据,包括请求的外部接口,特别是超时者部分,尽可能的交给task完成. 2.原来可以在入 ...

  3. CG-CTF(1)

    CG-CTF CG-CTF题目网址:https://cgctf.nuptsast.com/challenges#Web 第一题:签到题 查看页面源代码,得到flag(干杯~): 第二题:md5 col ...

  4. Taro 2.2 全面插件化,支持拓展和定制个性化功能

    自 2.2 开始,Taro 引入了插件化机制,允许开发者通过编写插件的方式来为 Taro 拓展更多功能或者为自身业务定制个性化功能,欢迎大家进行尝试,共同讨论~ 当前版本 2.2.1 官方插件 Tar ...

  5. zoj_2511 Design T-Shirt 贪心

    Design T-Shirt Time Limit: 2 Seconds      Memory Limit: 32768 KB Soon after he decided to design a T ...

  6. Linux下必知必会文件和目录

    转载于:https://blog.51cto.com/xiyuxingxia/2372712

  7. MySQL5.7 并行复制

    MySQL5.7 并行复制 1.缘由: 某天看到主从复制延时的告警有点频繁,就想着是不是彻底可以解决一下. 一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) ----->I ...

  8. Rust 1.31正式发布,首次引入Rust 2018新功能

    Rust 1.31是第一个实现了Rust 2018独有新功能并且不保证与现有代码库兼容的版本.Rust 2018相关工作正在进行中,而Rust 1.31只是整个三年开发周期的开始,这个开发周期将对这门 ...

  9. 《树莓派学习指南(基于Linux)》——本章小结

    本节书摘来自异步社区<树莓派学习指南(基于Linux)>一书中的第二章的本章小结,作者[英]Peter Membrey ,[澳]David Hows ,译者 张志博,孙峻文,更多章节内容可 ...

  10. NodeJS实现websocket代理机制

    使用的模块 ws http http-proxy 主要通过htt-proxy实现中转 启动websocket服务 var WebSocketServer = require('ws').Server; ...