Contest Link

为什么还没有 Official Editorial 啊……哦,原来是日文题解,那没事了。

A - Hands

有两幢 100 层的楼房 \(A,B\) ,将地面所在的楼层称为第一层楼。

\(\forall i\in[1,100],i\in Z\) ,\(A,B\) 的第 \(i\) 层有楼梯相连,通过时间为 \(x\) ; \(\forall i\in[1,99]\) ,\(A\) 的 \(i+1\) 层和 \(B\) 的第 \(i\) 层有楼梯相连,通过时间为 \(x\) .这些楼梯都是双向通行的。

\(A,B\) 楼内有直升的楼梯,第 \(i\) 层到第 \(i+1\) 层之间的通行时间为 \(y\) .

求从 \(B\) 的第 \(b\) 层到 \(A\) 的第 \(a\) 层的最短时间。

Thoughts & Solution

分讨题。

A的高层到B的低层 :如果 \(A_{i+1}\to B_i\to A_i\) (也就是 \(2x\) 的代价)不大于 \(A_{i+1}\to A_i\) (也就是 \(y\) 的代价),那么走到平层之后再到 \(B\) 即可,特判 \(A_{i+1}\to B_i\) 的情况。如果大于,那么就从 \(A\) 通过直升楼梯下去,走到平层之后再到 \(B\) .

A到B平层 :直接走过去。代价为 \(x\) .

B的高层到A的低层 :如果 \(B_{i+1}\to A_{i+1}\to B_i\) 不大于 \(B_{i+1}\to B_i\) ,那么这样走到比 \(a\) 高一层之后再:\(B_{a+1}\to A_{a+1}\to B_a\to A_a\) 即可,如果是本来就只高一层那么直接按这个走就好。如果大于,那么就同样直升下去,再到 \(A\) .

//Author: RingweEH
int a,b,x,y; int main()
{
a=read(); b=read(); x=read(); y=read();
int ans=0;
if ( a>b )
{
if ( 2*x<=y )
{
int del=a-b;
if ( del==1 ) ans=x;
else ans=x+(del-1)*2*x;
}
else ans=(a-b-1)*y+x;
}
if ( a==b ) ans=x;
if ( a<b )
{
if ( 2*x<=y )
{
int del=b-a;
if ( del==1 ) ans=3*x;
else ans=3*x+2*x*(del-1);
}
else ans=(b-a)*y+x;
}
printf( "%d",ans );
return 0;
}

B - Log

需要 \(n\) 段长度分别为 \(1,2,\dots n\) 的木条。现在有 \(n+1\) 个木条,长度为 \(1,2,\dots ,n+1\) ,每个代价为 1 ,买了之后可以砍任意次数,并扔掉不需要的部分。问满足需求的最低金额。

Thoughts & Solution

贪心取 \(n+1\) 并分成 \(1,2,\dots ,k\) ,二分即可。分完之后剩下的就从完整的里面直接拿。

注意二分上界不要设太大,不然就爆 long long 了(毕竟你要算 \(1\sim n\) 的和啊)。

//Author: RingweEH
ll n; int main()
{
scanf( "%lld",&n ); ll l=1,r=2e9,ans=-1;
while ( l<=r )
{
ll mid=(l+r)>>1;
if ( (mid*(mid+1)/2)<=(n+1) ) l=mid+1,ans=mid;
else r=mid-1;
} printf( "%lld\n",n-ans+1 ); return 0;
}

C - Large RPS Tournament

有 \(2^k\) 个人,从 \(0\sim 2^k-1\) 标号。给定一个长度为 \(n\) 的字符串 \(S\) ,R 表示石头,P 表示布,S 表示剪刀。第 \(i\) 个人只会出 \((i\bmod n+1)\) 的手势。两两晋级决定最后的 winner 。求胜者的手势。

Thoughts & Solution

这里有个极简做法。

看到题目就很容易想到倍增吧。然后直接每次将 \(S\) 复制一遍,两两算出胜者,然后作为新的 \(S\) ,这样做 \(k\) 次,然后取头就是答案了。

自己模拟一下很容易就理解为什么是对的吧。

//Author: RingweEH
ll n,k;
char win[230][230];
string str,dbstr; int main()
{
n=read(); k=read(); cin>>str;
win['R']['R']=win['R']['S']=win['S']['R']='R';
win['S']['S']=win['S']['P']=win['P']['S']='S';
win['P']['P']=win['P']['R']=win['R']['P']='P'; while ( k-- )
{
dbstr=str+str;
for ( int i=0; i<n; i++ )
str[i]=win[dbstr[i*2]][dbstr[i*2+1]];
} cout<<str[0]; return 0;
}

D - L

二维平面上一开始有三个点 \((0,0),(0,1),(1,0)\) 形成 \(L\) 形,每次操作可以改变一个点的位置使得仍然是 \(L\) 形。给出终止位置,求最小的移动步数。\(|x|,|y|\leq 1e9,T\leq 1e3\) .

Thoughts & Solution

题解链接

相当于是对于每个 L 形,找到一个唯一对应的点(题解里说是重心,但是个人感觉更像是 将这个 L 形所在的 \(2\times 2\) 的矩形作为一个整体,这个整体里面有 4 个点,分别对应 L 形拐角所在位置的 4 种情况 ,建立这样的一种点对点的对应关系),然后观察这个点随着 L 形移动的变化,会有 7 种方向可以走,然后就相当于二维平面上移动一个点,算一下然后再加上 “正好在不能走的位置上”的代价即可。

//Author: RingweEH
pair<int,int> node[3];
ll nowX,nowY; void turning()
{
sort( node,node+3 ); pair<int,int> mn=node[1];
for ( int i=0; i<3; i++ ) //左下角
mn.first=min( mn.first,node[i].first ),mn.second=min( mn.second,node[i].second );
nowX=mn.first*2ll; nowY=mn.second*2ll;
if ( node[0].second==node[2].second && node[1].first==node[0].first ) return;//对应点在左下角
if ( node[0].first+1==node[2].first && node[0].second+1==node[2].second )
{
if ( node[1].first==node[0].first ) nowY++; //对应点在左上
else nowX++; //右下
return;
}
nowX++; nowY++; //右上
} int main()
{
int T=read();
while ( T-- )
{
for ( int i=0; i<3; i++ )
node[i].first=read(),node[i].second=read(); turning(); ll ans=max( abs(nowX),abs(nowY) );
if ( nowX==nowY && nowX && (nowX^1) ) ans++; printf( "%lld\n",ans );
}
}

E - 1D Reversi Builder

有一排 \(n\) 个格子。\(A\) 先将每个格子等概率涂成黑色或者白色,设每个格子的颜色为 \(c_i\) 。

最开始,先在格子 \(S\) 上放一个和 \(c_S\) 同色的石子。

\(A,B\) 将按照以下步骤进行游戏,\(A\) 先手:

  • 选一个没有石子的格子 \(i\) 并放一个和格子同色的石子。
  • 寻找一个离 \(i\) 最近且放了和 \(i\) 同色的石子的格子 \(j\) ,并将 \(i,j\) 之间所有格子的石子颜色变成 \(i\) 的石子颜色。

当没有空的格子时,游戏结束。

\(A\) 要最大化最终的黑色石子个数,\(B\) 则最大化白色。对于所有的 \(S=1,2,\dots,n\) ,求最终黑色石子个数的期望。

答案对 \(998244353\) 取模,\(1\leq n\leq 2e5\) .

Thoughts & Solution

有结论:连续段内不会出现 黑-白-黑 的情况

如果出现了,设两个黑色的位置从左到右是 \(x,y\) (假定 \(x\) 先放)。

那么 \(y\) 右边一定有 \(y'\) 否则就会和 \(x\) 配对,而去掉 \(y\) 后剩下 \(x,y'\) 。

这样归纳下去,一定是有一次不能再推了,就出现了矛盾。所以这样的情形是不可能出现的。

同理也可以说明 白-黑-白 的情形不会出现。

那么就可以得到,每一次操作之后,除了没有放石子的格子,其他格子的石子排布一定形成了两个颜色相同的连续段。

现在就可以对序列两端的颜色进行讨论了。

  • 如果 \(c_1=c_n\) ,由结论,显然可以知道最后的局面一定全是端点颜色。
  • 如果 \(c_1\neq c_n\) ,不妨设 \(c_1=black,c_n=white\) .令 \(x\) 为最靠左端的白色块位置,\(y\) 为最靠右端的黑色块位置。显然,这样答案在最坏情况下的上下界是 \([1,x)\) ,最好情况下是 \([1,y]\) .现在就在于 \(x-1\) 和 \(y+1\) 取的顺序了。
    • 如果 \(x-1\) 先取,那么当选了 \(y\) 之后,\([1,y]\) 必然都是黑色且不会再改变,达到上限。因此,如果 \(x-1\) 到 \(S\) 的距离不大于 \(S\) 到 \(y+1\) 的距离,那么答案就是 \([1,y]\) .
    • 如果 \(y+1\) 先取,类似地有 \([x,n]\) 为白色,取到下限。因此,如果 \(x-1\) 到 \(S\) 的距离大于 \(S\) 到 \(y+1\) 的距离,答案就是 \([1,x)\) .

按照这个东西算一算就好了。

//Author: RingweEH
const int N=2e5+10;
const ll Mod=998244353;
int n;
ll Inv2,powe2[N*2],f[N],ans[N]; ll power( ll a,ll b )
{
ll res=1;
for ( ; b; b>>=1,a=a*a%Mod )
if ( b&1 ) res=res*a%Mod;
return res;
} void init()
{
powe2[0]=1;
for ( int i=1; i<=n*2; i++ )
powe2[i]=powe2[i-1]*2%Mod;
} int main()
{
n=read(); if ( n==1 ) { printf( "%lld\n",power(2,Mod-2) ); return 0; }
init(); ll sum=0; sum=(sum+powe2[n-2]*n)%Mod; sum=(sum+powe2[n-2]*n)%Mod;
for ( int i=1; i<=n; i++ )
ans[i]=sum;
for ( int i=2; i<=n; i++ )
f[i]=(f[i-1]+(2*i-1)*powe2[2*i-3])%Mod;
for ( int i=3; i<=n-2; i++ )
ans[i]=(ans[i]+f[i-max(2*i-n,1)]-f[1]+Mod)%Mod;
ll inv2=power( powe2[n],Mod-2 );
for ( int i=1; i<=n; i++ )
ans[i]=ans[i]*inv2%Mod; for ( int i=1; i<=n; i++ )
printf( "%lld\n",ans[i] );
return 0;
}

Magic

这里有一份来自 @hehezhou 的奇妙递推代码……呵姥爷yyds!

#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
inline int power(int a, int b) {
long long res = a, ans = 1;
for (; b; b >>= 1, res = res * res % mod) if (b & 1) ans = ans * res % mod;
return ans;
}
int ans[200010];
int main() {
ans[1] = ans[2] = 0, ans[3] = 6, ans[4] = 46;
int n;
scanf("%d", &n);
for (int i = 5; i <= n; i++) {
ans[i] = (9ll * ans[i - 1] + 998244329ll * ans[i - 2] + 16ll * ans[i - 3]) % mod;
}
int qwq = 1ll * power(2, mod - 2) * n % mod;
for (int i = 1; i <= n; i++) {
int cur = 1ll * ans[min(i, n + 1 - i)] * power(2, mod - 1 - n) % mod;
printf("%d\n", (qwq + cur) % mod);
}
}

F - 1D Kingdom Builder

有一行格子,其中小于 \(0\) 的为白色,大于 \(n\) 的为黑色,中间的格子颜色给定。一些格子需要被标记,按以下规则进行:

  • 选择一个颜色 \(col\) ,找到一个未标记的、旁边有标记点的、颜色为 \(col\) 的格子,并标记
  • 如果找不到,就找任意一个颜色为 \(col\) 的格子

求标记完所有格子的最少操作次数。 \(n\leq 1e5\) .

Thoughts & Solution

题解链接

Warning:属于 【题单】最近遇见的 SHIT DP题 三连 ,题单 适合用于自虐和消磨时间 ,请谨慎考虑自身生命安全

Unfinished.

AtCoder Regular Contest 109的更多相关文章

  1. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  2. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  3. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  4. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  5. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  6. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

  7. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

  8. AtCoder Regular Contest 096

    AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...

  9. AtCoder Regular Contest 097

    AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...

随机推荐

  1. 主动关闭 tcp_timewait_state_process 处理

    正常情况下主动关闭连接的一端在连接正常终止后,会进入TIME_WAIT状态,存在这个状态有以下两个原因(参考<Unix网络编程>):      1.保证TCP连接关闭的可靠性.如果最终发送 ...

  2. wait函数与waitpid函数(僵尸进程)

    当子进程退出时,内核会向父进程发送SIGCHLD信号,子进程的退出是个异步事件(子进程可以在父进程运行的任何时刻终止) 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程.它只保留最小的一些 ...

  3. python学习手册.first

    # 1.注释 # 行注释  #         # print('****')     # 多行注释三个双引号或者单引号         '''print('****')            pri ...

  4. 04、MyBatis DynamicSQL(Mybatis动态SQL)

    1.动态SQL简介 动态 SQL是MyBatis强大特性之一. 动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似. MyBatis 采用功能强大的基于 OGNL 的表达式来 ...

  5. 想换4K显示器了?那你搞懂啥是4K了吗?

    前言 我们在科技资讯以及电脑显示器.数字电视等电子产品的宣传语中,经常能够看见4K的字样.最近,B站(哔哩哔哩)升级了HTML5播放器和视频云等相关服务,为广大用户提供了超高清(UHD: Ultra ...

  6. Math.floor(Math.random() * array.length),splice

    1.Math.floor(Math.random() * array.length) 返回长度内的索引 eg: changeLimit () { function getArrayItems(arr, ...

  7. Python 调用接口添加头信息

    import requests,jsonurl = 'http://47.108.115.193:9000/tb-store/store/getWechatAppHome'header={" ...

  8. FL studio系列教程(十):FL Studio中如何新建样本

    FL Studio中强调以样本为核心的编曲模式.样本其实就是一个小的音序片段,可以是单独的乐器或单独的打击乐,还可以是他们组合的一个小音序片段,它是我们学习编曲的最基础知识.所以本文主要为大家讲解的是 ...

  9. 「CSP-S 2020」动物园

    description luogu loj(暂无数据) solution 这道题作为T2,对选手们考试开始后先通看一遍所有题目的好习惯,以及判断究竟谁才是真正的签到题的重要能力进行了较好的锻炼, 特别 ...

  10. pytest失败重跑

    一.说明 平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来.自动化运行用例时候,也会出现偶然的bug,可以针对单个用例 ...