【学习笔记】[AGC033E] Go around a Circle

不妨假设 S 0 = R S_0=R S0=R,做出如下观察:
1.1 1.1 1.1 不存在 B B B的连续段
1.2 1.2 1.2 不存在长度为偶数的 R R R的连续段
1.3 1.3 1.3 对于 S i = L S_i=L Si=L的情况,事实上这个棋子的移动方向是确定的,取决于上一段 R R R的奇偶性
1.4 1.4 1.4 S S S中连续的 R R R最短为 Y Y Y,如果圆上任意圆弧的长度 ≤ Y \le Y Y,那么可以从圆弧一端走到另一端,因此一定合法。能否证明这是充要的呢?取最长一段圆弧和最短一段 R R R,从圆弧的两端出发逆序操作就能找到出发点。因为圆弧两端奇偶性不同,因此必然存在一个点跨过了整段圆弧,证毕。 注意,我们只考虑长度为奇数的连续的 R R R
1.5 1.5 1.5对于 S S S中长度为偶数的连续的 R R R,发现可以缩掉,这样会出现连续的 B B B,那么只要不是出现在开头,这些 B B B都没有影响,因此如果开头的 R R R是奇数,那么不用考虑,如果是偶数,设长度为 Z Z Z,那么圆弧长度不能超过 Z + 1 Z+1 Z+1,据此对 Y Y Y修正即可。

大力 d p dp dp即可。复杂度 O ( n ) O(n) O(n)

似乎细节比较多

#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; const int mod=1e9+7; int n,m,a[200005],L(inf); ll dp[200005][2],f[200005],res; string s; ll ask(int i,int j){ return i<=0?0:dp[i][j]; } signed main(){ cin>>n>>m>>s;for(int i=0;i<m;i++)a[i+1]=(s[i]=='R'); if(!a[1])for(int i=1;i<=m;i++)a[i]^=1; int j=1; for(int i=1;i<=m;i++){ if(!a[i]){ if((i-j)&1)L=min(L,i-j); else if(j==1)L=min(L,i); j=i+1; } }if(L==inf){ f[1]=1;res=n+1; for(int i=2;i<n;i++){ ll x=f[i-2]; f[i]=(f[i-1]+x)%mod; res=(res+(n-i+1)*x)%mod; }cout<<res<<"\n"; return 0; } dp[1][1]=1;if(L>=n-1&&(n-1&1))res=n; for(int i=2;i<n;i++){ ll x=ask(i-1,i&1)-ask(i-L-2,i&1); dp[i][i&1]=(dp[i-1][i&1]+x)%mod; dp[i][!(i&1)]=dp[i-1][!(i&1)]; if(n-i<=L&&(n-i&1))res=(res+(n-i+1)*x)%mod; } cout<<(res+mod)%mod; }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530044.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(10)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2022-01-29 树上斜率优化
点击右上角即可分享
微信分享提示