归纳每一次操作后必然是两个颜色相同的连续段(即ww...bb...或bb...ww...),对操作的位置分类讨论不难证明正确性

当$c_{1}=c_{n}$,由于端点颜色不会修改,再根据该结论,可以得到$f(s,c_{i})=c_{1}\cdot n$(w为0,b为$n$)

当$c_{1}\ne c_{n}$(以下假设$c_{1}=b$且$c_{n}=w$),令$x=\min_{c_{i}=w}i$且$y=\max_{c_{i}=b}i$,考虑答案的上下限,最坏情况下即为$[1,x)$,最好情况下为$[1,y]$

对$x-1$和$y+1$哪个先取分类讨论:

1.若$x-1$先取,则当选择$y$后(也有可能是先选$y$再选$x-1$,但同理),$[1,y]$必然都为黑色(且不会再被翻转),即达到上限,因此如果$x-1$到$s$的距离小于等于$s$到$y+1$的距离,则答案为$[1,y]$

2.若$y+1$先取,类似的可以得到$[x,n]$都为白色,即答案取到下限$[1,x)$,因此如果$x-1$到$s$的距离大于$s$到$y+1$的距离,则答案为$[1,x)$

(另外对于$c_{1}=w$且$c_{n}=b$,不是两倍而是$s'=n-s+1$时的答案)

这显然包含了所有情况,即答案仅与$x$、$y$和$s$有关,得到了一个暴力$o(n^{3})$的做法,代码如下

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 int n,mi[N],ans[N];
6 int main(){
7 scanf("%d",&n);
8 if (n==1){
9 printf("%d",(mod+1)/2);
10 return 0;
11 }
12 mi[0]=1;
13 for(int i=1;i<=n;i++)mi[i]=mi[i-1]*2%mod;
14 for(int i=2;i<=n;i++){
15 for(int j=1;j<=n;j++)ans[j]=(ans[j]+i-1)%mod;
16 for(int j=i+1;j<n;j++)
17 for(int k=1;k<=n;k++)
18 if (abs(i-1-k)<=abs(j+1-k))ans[k]=(ans[k]+1LL*j*mi[j-i-1])%mod;
19 else ans[k]=(ans[k]+1LL*(i-1)*mi[j-i-1])%mod;
20 }
21 int inv=1;
22 for(int i=1;i<=n;i++)inv=1LL*(mod+1)/2*inv%mod;
23 for(int i=1;i<=n;i++)printf("%lld\n",(ans[i]+ans[n-i+1]+1LL*mi[n-2]*n)%mod*inv%mod);
24 }

将$y=x-1$的特殊情况累加后即为$\frac{n(n-1)}{2}$,然后对于$k$的枚举改为差分,时间复杂度降为$o(n^{2})$,代码如下

 1     for(int i=2;i<=n;i++)
2 for(int j=i+1;j<n;j++){
3 int k=(j+i)/2;
4 ans[1]=(ans[1]+1LL*j*mi[j-i-1])%mod;
5 ans[k+1]=(ans[k+1]-1LL*(j-i+1)*mi[j-i-1]%mod+mod)%mod;
6 }
7 for(int i=2;i<=n;i++)ans[i]=(ans[i]+ans[i-1])%mod;
8 int inv=1,s=1LL*n*(n-1)/2%mod;
9 for(int i=1;i<=n;i++){
10 inv=1LL*(mod+1)/2*inv%mod;
11 ans[i]=(ans[i]+s)%mod;
12 }

进一步的,对于$ans[1]$的修改比较好处理,对于$ans[k+1]$的修改可以枚举$j-i$,那么$k=\frac{j-i}{2}+i$,再进行一次差分即可,时间复杂度即降为$o(n)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define mod 998244353
5 int n,mi[N],ans[N];
6 int main(){
7 scanf("%d",&n);
8 if (n==1){
9 printf("%d",(mod+1)/2);
10 return 0;
11 }
12 mi[0]=1;
13 for(int i=1;i<=n;i++)mi[i]=mi[i-1]*2%mod;
14 for(int i=1;i<=n-3;i++){
15 ans[i/2+3]=(ans[i/2+3]-1LL*(i+1)*mi[i-1]%mod+mod)%mod;
16 ans[i/2+n-i+1]=(ans[i/2+n-i+1]+1LL*(i+1)*mi[i-1]%mod)%mod;
17 }
18 for(int i=2;i<=n;i++)ans[i]=(ans[i]+ans[i-1])%mod;
19 for(int i=3;i<n;i++)ans[1]=(ans[1]+1LL*i*(mi[i-2]-1))%mod;
20 for(int i=2;i<=n;i++)ans[i]=(ans[i]+ans[i-1])%mod;
21 int inv=1,s=1LL*n*(n-1)/2%mod;
22 for(int i=1;i<=n;i++){
23 inv=1LL*(mod+1)/2*inv%mod;
24 ans[i]=(ans[i]+s)%mod;
25 }
26 for(int i=1;i<=n;i++)printf("%lld\n",(ans[i]+ans[n-i+1]+1LL*mi[n-2]*n)%mod*inv%mod);
27 }

[atARC109E]1D Reversi Builder的更多相关文章

  1. I - 一次元リバーシ / 1D Reversi(水题)

    Problem Statement Two foxes Jiro and Saburo are playing a game called 1D Reversi. This game is playe ...

  2. 2018.09.20 atcoder 1D Reversi(模拟)

    传送门 考虑每次摆石头都会消去最外层的一个连续颜色串. 所以只用统计一下有多少段颜色即可. 代码: #include<bits/stdc++.h> using namespace std; ...

  3. ARC109F - 1D Kingdom Builder

    一行格子,其中小于\(0\)的格子为白色,大于\(n\)的格子为黑色,中间的格子颜色由题目给出. 有一些格子需要被标记.标记按照以下规则进行:选择一个颜色\(c\),找到一个未标记的 旁边有标记点的 ...

  4. [atARC109F]1D Kingdom Builder

    考虑最终有石子的位置的状态,判断一种状态是否可行 反过来,依次删除石子,删除条件是:当删除的石子是该段最后一个(即其两边都没有石子了),要求除其以外,每个连续段旁边的两个点都与其颜色不同 构造一种删除 ...

  5. AtCoder Regular Contest 109

    Contest Link 为什么还没有 Official Editorial 啊--哦,原来是日文题解,那没事了. A - Hands 有两幢 100 层的楼房 \(A,B\) ,将地面所在的楼层称为 ...

  6. atcoder题目合集(持续更新中)

    Choosing Points 数学 Integers on a Tree 构造 Leftmost Ball 计数dp+组合数学 Painting Graphs with AtCoDeer tarja ...

  7. 【AtCoder】ARC063

    ARC063 C - 一次元リバーシ / 1D Reversi 不同的颜色段数-1 #include <bits/stdc++.h> #define fi first #define se ...

  8. 23种设计模式--建造者模式-Builder Pattern

    一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...

  9. PHP设计模式(五)建造者模式(Builder For PHP)

    建造者模式:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示的设计模式. 设计场景: 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,爱好等信息,才能获得用 ...

随机推荐

  1. Java秘诀!Java关系运算符介绍

    运算符丰富是 Java 语言的主要特点之一,它提供的运算符数量之多,在高级语言中是少见的. Java 语言中的运算符除了具有优先级之外,还有结合性的特点.当一个表达式中出现多种运算符时,执行的先后顺序 ...

  2. 小白自制Linux开发板 七. USB驱动配置

    本文章基于https://whycan.com/t_3087.htmlhttps://whycan.com/t_6021.html整理 F1c100s芯片支持USB的OTG模式,也就是可以通过更改Us ...

  3. UltraSoft - Beta - Scrum Meeting 8

    Date: May 24th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 记录Scrum Meeting Liuzh 前端 暂无 Kkkk 前端 暂无 王f ...

  4. Request failed with status code 500以及自引用循环Self referencing loop detected for property ‘xx‘ with type

    错误Error: Request failed with status code 500 ,调试前端没问题,后端也没问题,还报错"连接超时" 在Network中找到错误Self r ...

  5. Spark面试题(二)

    首发于我的个人博客:Spark面试题(二) 1.Spark有哪两种算子? Transformation(转化)算子和Action(执行)算子. 2.Spark有哪些聚合类的算子,我们应该尽量避免什么类 ...

  6. 为什么用于开关电源的开关管一般用MOS管而不是三极管

    区别: 1.MOS管损耗比三极管小,导通后压降理论上为0. 2.MOS管为电压驱动型,只需要给电压即可,意思是即便串入一个100K的电阻,只要电压够,MOS管还是能够导通. 3.MOS管的温度特性要比 ...

  7. stm32知识学习的先后顺序

    这里大概的罗列了一些学习STM32的内容,以及学习顺序.如果是新手的话,建议边看中文手册和学习视频;如果是已经入门的,个人建议自己做一个项目,不论项目大小,当然里面会涉及到自己已经学习过的,或者是自己 ...

  8. 字符串与模式匹配算法(四):BM算法

    一.BM算法介绍 BM算法(Boyer-Moore算法)是罗伯特·波义尔(Robert Boyer)和杰·摩尔(J·Moore)在1977年共同提出的.与KMP算法不同的是,BM算法是模式串P由左向右 ...

  9. vcs命令

    转载:VCS_weixin_34256074的博客-CSDN博客 timing check相关的: +notimingcheck命令,可以用在compile时,也可以用在run time的时候, 都是 ...

  10. 神经网络 感知机 Perceptron python实现

    import numpy as np import matplotlib.pyplot as plt import math def create_data(w1=3,w2=-7,b=4,seed=1 ...