心路历程

预计得分:100 + 40 + 30 = 170

实际得分:100 + 30 + 0 = 130

T2有一个部分分的数组没开够RE了。

T3好像是思路有点小问题。。 思路没问题,实现的时候一个细节没想过来。。

Sol

T1

直接把式子化开,发现都可以$O(1)$维护,做完了。。。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<vector>
  4. #define LL long long
  5. using namespace std;
  6. const LL MAXN = 1e5 + ;
  7. inline LL read() {
  8. char c = getchar(); LL x = , f = ;
  9. while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
  10. while(c >= '' && c <= '') x = x * + c - '', c = getchar();
  11. return x * f;
  12. }
  13. LL N, a[MAXN], sum, sump;
  14. int main() {
  15. N = read();
  16. for(LL i = ; i <= N; i++) a[i] = read(), sum += a[i], sump += a[i] * a[i];
  17. for(LL i = ; i <= N; i++) {
  18. LL ans = (N - ) * (sump - a[i] * a[i]) - * (sum - a[i]) * (sum - a[i]) + (sum - a[i]) * (sum - a[i]);
  19. if(i != N) printf("%lld ", ans);
  20. else printf("%lld", ans);
  21. }
  22. return ;
  23. }

T1

T2

好难啊,$30$分的枚举颜色dp应该比较好想把,$f[i][j]$表示第$i$个位置,填了$j$个颜色,然后先枚举一下$1$的颜色,前缀和优化一下,$O(n a_i^2)$

正解:

考虑容斥,令$f[i]$表示第$i$个位置的答案

什么都不考虑:$f[i] = f[i - 1] \times a[i]$

这时候会算重第$i$个位置和第$i - 1$个位置相同的情况,减去$f[i-2] * min(a[i], a[i - 1])$

然后会多减去$i - 2, i - 1, i$这三个位置相同的情况,加上$f[i - 3] * min(a[i], a[i  -1], a[i - 2])$

不断容斥下去。

$f[i] = \sum_{j} (-1)^{i - j} f[i - j + 1] * min(a_{(i - j)  \ to \  i})$

但是还有一个问题:这玩意儿是环形的,还需要考虑$1$和$i$不同的情况,。。。

这就很麻烦了,因为$1$和$i$的高度问题很难讨论。

我们直接把序列转一转,令$1$号位置的元素最小,这样$1$号元素不论取什么,$n$号位置一定会少一种取法

考虑如何优化这玩意儿,稍微化简一下,式子就变成了这样(负变正不影响奇偶性)

$f[i] = (-1)^i \sum_{j} (-1)^j f[i - j +1] \times min(a_{(i - j) \  to \  i})$

把$(-1)^j $和$f$看成一项,这东西显然有单调性。

考虑用单调栈去维护

具体做法是:考虑从$i$转移到$i+1$时答案的变化

一种情况是$a[i+1] > a[i]$这时候直接加上$i+1$的贡献即可

另一种情况是$a[i+1] < a[i]$,这时候前面的一些元素对答案的贡献会减小,用单调栈维护,找到第一个小于等于它的,减去这之间的位置的贡献即可。

时间复杂度:$O(n)$

代码中还用到了一个容斥。上面说的dp是不考虑$1$号位置与$i$号位置相同的情况

设$g_i$表示$1$与$i$拼成环相同时的方案数,稍微观察一下不难发现$g_i = f_{i - 1} - g_{i - 1}$。(把$1$和$i$看成相同的元素)

需要注意的是$g_2 = 0$,因此到达$2$时就需要停止

其实这个容斥方法也可以用来求该问题没有$a_i$限制时的通项公式。

代码较为高能,请谨慎查看。。

  1. /*
  2.  
  3. */
  4. #include<iostream>
  5. #include<cstdio>
  6. #include<cstring>
  7. #include<algorithm>
  8. #include<map>
  9. #include<vector>
  10. #include<set>
  11. #include<queue>
  12. #include<cmath>
  13. //#include<ext/pb_ds/assoc_container.hpp>
  14. //#include<ext/pb_ds/hash_policy.hpp>
  15. #define Pair pair<LL, LL>
  16. #define MP(x, y) make_pair(x, y)
  17. #define fi first
  18. #define se second
  19. //#define LL long long
  20. #define LL long long
  21. #define ull unsigned long long
  22. #define rg register
  23. #define pt(x) printf("%d ", x);
  24. using namespace std;
  25. //using namespace __gnu_pbds;
  26. const LL MAXN = 1e6 + , INF = 1e9 + , mod = 1e9 + ;
  27. const double eps = 1e-;
  28. inline LL read() {
  29. char c = getchar(); LL x = , f = ;
  30. while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
  31. while(c >= '' && c <= '') x = x * + c - '', c = getchar();
  32. return x * f;
  33. }
  34. LL N, a[MAXN], b[MAXN], f[MAXN], top;
  35. Pair s[MAXN];
  36. LL id(LL x) {
  37. return x & ? (-) : ;
  38. }
  39. int main() {
  40. N = read();
  41. LL mn = INF, pos = , cnt = ;
  42. for(LL i = ; i <= N; i++) {
  43. a[i] = read();
  44. if(a[i] < mn) mn = a[i], pos = i;
  45. }
  46. for(LL i = ; i <= N; i++) b[i] = a[pos], pos = pos % N + ;
  47. memcpy(a, b, sizeof(b));
  48. // for(LL i = 1; i <= N; i++) printf("%d ", b[i]);
  49. f[] = -;
  50.  
  51. /*for(LL i = 1; i <= N; i++) {
  52. LL opt = 1, mn = INF;
  53. for(LL j = i; j >= 1; j--) {
  54. mn = min(a[j], mn);
  55. f[i] = (f[i] + opt * f[j - 1] * mn + mod) % mod;
  56. opt = (opt == 1 ? -1 : 1);
  57. }
  58. }*/
  59. LL sum = ; s[++top] = MP(, );LL ans = ;
  60. for(int i = ; i <= N; i++) {
  61. LL now = ;
  62. while(top && a[i] <= s[top].fi) {
  63. sum = (sum - s[top].fi * s[top].se % mod) % mod;
  64. now += s[top].se;
  65. top--;
  66. }
  67. now = (now + f[i - ]) % mod;
  68. //sum += id(i) * a[i] * now;
  69. f[i] = sum + a[i] * now % mod;
  70.  
  71. if(i & ) f[i] = -f[i];
  72. f[i] = (f[i] + mod) % mod;
  73.  
  74. if(i != )
  75. if((N - i) & ) ans = (ans - f[i] + mod) % mod;
  76. else ans = (ans + f[i]) % mod;
  77.  
  78. if((i - ) & ) f[i] = -f[i];
  79. f[i] = (f[i] + mod) % mod;
  80.  
  81. s[++top] = MP(a[i], now);
  82. (sum = sum + now * a[i] % mod + mod) %= mod;
  83. }
  84.  
  85. /*for(int i = N; i >= 2; i--)
  86. if((N - i) & 1) ans = (ans - abs(f[i]) + mod) % mod;
  87. else ans = (ans + abs(f[i])) % mod; */
  88. //for(LL i = 1; i <= N; i++) printf("%I64d\n", f[i]); //puts("");
  89. cout << (ans + mod) % mod;
  90. return ;
  91. }
  92. /*
  93. 6
  94. 987 654 321 87 54 321 1
  95.  
  96. 10
  97. 154 542 12 1 4354 2 12 121 2 45
  98.  
  99. 4
  100. 3 5 1 2
  101.  
  102. 4
  103. 4 4 4 4
  104.  
  105. 3
  106. 3 3 3
  107.  
  108. 2
  109. 2 3
  110.  
  111. 1
  112. 4
  113. */

T2

T3

先考虑$m = 0$时。

定义$lowbit(i)$表示$i$的二进制下第一个为$1$的位置,很显然,如果我们把$lowbit(x)$相等的元素全都分给其中一个玩家这样一定是合法的。

每一个$i$能够贡献的数量为$2^{n - i}$。直接对$k$二进制拆分即可。考场上想到了,但是实现的时候傻乎乎的以为每次拆分的时候二进制位不能有重叠。。

$m \not = 0$的时候好像是个神仙dp,明天再看。。咕咕咕

牛客NOIP提高组(二)题解的更多相关文章

  1. 牛客NOIP提高组(三)题解

    心路历程 预计得分:$30 + 0 + 0 = 30$ 实际得分:$0+0+0= 0$ T1算概率的时候没模爆long long了... A 我敢打赌这不是noip难度... 考虑算一个位置的概率,若 ...

  2. 牛客NOIP提高组R1 C保护(主席树)

    题意 题目链接 Sol Orz lyq 我们可以把一支军队(u, v)拆分为两个(u, lca)和(v, lca) 考虑一个点x,什么时候军队对它有贡献,肯定是u或v在他的子树内,且lca在他的子树外 ...

  3. 牛客NOIP提高组R1 A中位数(二分)

    题意 题目链接 Sol 很神仙的题目啊,考场上只会$n^2$的暴力.. 考虑直接二分一个$mid$,我们来判断最终答案是否可能大于$x$. 判断的时候记录一下前缀最小值即可, 设$s[i]$表示$1- ...

  4. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  5. 牛客CSP-S提高组赛前集训营1

    牛客CSP-S提高组赛前集训营1 比赛链接 官方题解 before:T1观察+结论题,T2树形Dp,可以换根或up&down,T3正解妙,转化为图上问题.题目质量不错,但数据太水了~. A-仓 ...

  6. 18/9/16牛客网提高组Day2

    牛客网提高组Day2 T1 方差 第一眼看就知道要打暴力啊,然而并没有想到去化简式子... 可能因为昨晚没睡好,今天上午困死 导致暴力打了一个半小时,还不对... #include <algor ...

  7. 18/9/9牛客网提高组Day1

    牛客网提高组Day1 T1 中位数 这好像是主席树??听说过,不会啊... 最后只打了个暴力,可能是n2logn? 只过了前30%  qwq #include<algorithm> #in ...

  8. 牛客网 提高组第8周 T1 染色

    染色 链接: https://ac.nowcoder.com/acm/contest/176/A 来源:牛客网 题目描述 \(\tt{fizzydavid}\)和\(\tt{leo}\)有\(n\)个 ...

  9. 牛客网 提高组第8周 T2 推箱子 解题报告

    推箱子 链接: https://ac.nowcoder.com/acm/contest/176/B 来源:牛客网 题目描述 在平面上有\(n\)个箱子,每个箱子都可以看成一个矩形,两条边都和坐标轴平行 ...

随机推荐

  1. 【245】◀▶IEW-Unit10

    Unit 10 Censorship 1. Model1题目及范文分析 Some parents believe that there is no harm in allowing their chi ...

  2. fkmu

    杭州赛区J:考虑实质上是求解 (a,b) = 1 且 a*b<=n的数对个数,枚举a,对b容斥. trickgcd:考虑反向求解,即为ans[x] -= ans[t*x],注意到因为反向求所以余 ...

  3. editplus怎么在前后插入字符

    快捷键:ctrl+h 未编辑之前: 源: 一:行首批量添加   查找"^" 替换为“我是行首aaa” 二: 行尾批量添加   查找"\n" 替换为“'bbb我是 ...

  4. B - Simple Game

    B - Simple Game Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Su ...

  5. 21.运行Consent Page

    服务端把这个地方修改为true,需要设置 运行测试.服务端和客户端都运行起来 我们使用的用户是在这里配置的 服务端修改ConsentController 再次运行,但是页面都是乱码 openId和pr ...

  6. 使用go实现基于命令行的计算器程序

    项目目录结构 calcs.go源文件 package main import ( "fmt" "os" "strconv" "my ...

  7. MVC+Linq+EF笔记

    using (DataContext ctx = new DataContext()) { /*foreach (var item in ctx.employees) { ViewData[" ...

  8. IOC模式及Unity框架文章收藏

    1.IoC模式:http://www.cnblogs.com/qqlin/archive/2012/10/09/2707075.html 通过Unity实现IOC容器. 2.深入理解DIP.IoC.D ...

  9. udp通信的消息处理方案

    0.引言 大家都知道当使用udp通信时,最大的一个问题是会出现丢包的情况,那么如何可以既使用udp来传输,又同时能有效防止丢包呢? 本文提供一种简单有效的方法,可以显著避免udp丢包的问题.此外,如果 ...

  10. QxOrm 1.2.9 下载 以及编译方法 简介.

    QxOrm 是一个基于QT开发的数据库方面的ORM库,功能很强大,是QT C++数据开发方面的好工具. 目前已经更新1.3.1 .但 不幸的是 它的官网http://www.qxorm.com/ 莫名 ...