乱搞 寿司
来源:互联网 发布:20174g网络哪家网速快 编辑:程序博客网 时间:2024/04/26 17:13
题面去内网找。。
第一思路当然是找一个位置成为断点,让所有的移动都不经过它,让一部分点到这个断点的两侧。很明显是有符合方案的,并且在所有枚举中有一种是最优解。
于是我考试时打了O(N^2)的暴力。。。。枚举每一个点是要移动到左边还是右边。而实际上是可以找到一个边界之后用前缀和,找边界可以二分。O(N*logN),如果数据水可以卡过去。
但是,如果移动红点,枚举每一个蓝点作为断点,边界就是最中间一个蓝点的位置(在这里左右蓝点数一样,向左一个红点就一定向左移动比较优,向右同理)。而断点向右移动一个,边界也会移动一个蓝点,那么二分干嘛。。直接找就好了。
以蓝点记录区间里红点的个数,拉成链(可以考虑把最后一个蓝点搞成第0个蓝点),然后搞个前缀和。维护一个sum的值表示搞到这里的答案,找到边界后,因为是断点右移,那么边界以左的红点走的步数-1,以右的+1.因为有红点的前缀和,搞起来就很容易了。
还有一个坑,边界右移后会越过一些红点,导致它们的答案压根不会发生改变。但是如果蓝点是偶数个,位于两边界间的红点其实是在真正的边界上(最中间应该是两蓝点的中间部分,两蓝点都在边界两侧),这些红点对于边界在他左边一个和在他右边一个都是一样的。但是如果有奇数个蓝点就不太一样了,就要减去多出来的(也就是当他在边界以右,而实际上越到边界左侧的红点,他们对答案并没产生额外贡献)
#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <cstring>#define ll long long#define N 1001005using namespace std;int t,n;char s[N];ll b,r,ans,now,a[N*2];int main(){ scanf("%d",&t); while(t--) { scanf("%s",s+1);n=strlen(s+1);b=r=now=ans=0; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) if(s[i]=='R')r++,a[b]++; else b++; for(ll i=1;i<b;i++)now+=min(i,b-i)*a[i]; ans=now;a[0]+=a[b]; for(int i=b;i<b*2;i++)a[i]=a[i-b]; for(int i=1;i<b*2;i++)a[i]+=a[i-1]; for(int i=1;i<b;i++) { ll l=a[i+(b>>1)-1]-a[i-1];now-=l;now+=r-l; if(b&1)now-=a[i+(b>>1)]-a[i+(b>>1)-1]; ans=min(ans,now); } printf("%lld\n",ans); }}
阅读全文
0 0
- 乱搞 寿司
- 寿司?
- 乱搞
- 乱搞
- 回转寿司
- 寿司説明
- 那天去吃寿司
- 最新寿司美食
- 绿草寿司吧起源
- 寿司之神--小野二郎
- 寿司晚宴(dinner)
- BZOJ4627 [BeiJing2016]回转寿司
- NOI 2015 寿司晚宴
- BZOJ4197 [Noi2015]寿司晚宴
- 4197: [Noi2015]寿司晚宴
- 4627: [BeiJing2016]回转寿司
- bzoj4197 [Noi2015]寿司晚宴
- 洛谷P2150 寿司晚宴
- Tornado框架08-应用安全
- 2017-10-16总结第六天
- C++的存储区
- 胡同门牌号--蓝桥杯A1
- Chris Richardson 微服务系列 第三篇 构建微服务之:微服务架构中的进程间通信
- 乱搞 寿司
- isNaN()对"" 和" " 会返回false
- dubbo几个错误解决方案 可行
- 1070. Mooncake (25)
- 网络层服务
- 替换空格
- Java项目
- 回文字符,最小删除问题
- 操作符