这题也是挺神仙的,现在O(n)的解法还没打出来,只是用O(nlogn)卡过去了(理论上可以过),sdfz某大佬用三分拿到了65分……

考试连暴力都没打出来……

n2暴力T40:

首先将环拆成链,我们可以O(n)枚举一个点不动,将它左右的点向他靠近,总复杂度O($n^2$).

代码也挺简单,貌似我的代码比别人都短……可能思路有点不一样。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define MAXN 2000010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
char a[MAXN];
int n,T;
signed main()
{
cin>>T;
while(T--)
{
n=;char te=getchar();
while(te!='B'&&te!='R')te=getchar();
while(te=='B'||te=='R'){a[++n]=te;te=getchar();}
for(int i=n+;i<*n;i++)a[i]=a[i-n];
LL ans=0x7fffffff;
for(int i=;i<=n;i++)
{
LL sum=,nb=,nr=;
for(int j=i+n-;j>=i+n-n/;j--)
if(a[j]==a[i])sum+=i+n-j-nb-,nb++;
for(int j=i+;j<=i+n/;j++)
if(a[j]==a[i])sum+=j-i--nr,nr++;
if(n%==&&a[i+n/]==a[i])sum+=min(n/-nb-,n/-nr-);
ans=min(ans,sum);
}
cout<<ans<<endl;
}
}

nlogn二分:

对于一段序列,一定有一个分界点,将它左边的红色移到左端,右边的红色移到右端使得答案最优,而此时左右另一种颜色各占一半(我觉得有点难以理解),所以这个分界点可以二分查找,加上枚举序列起点总复杂度nlogn。

另外还有一个难点就是O(1)求步数。

预处理出i点左右红色数量rl,rr,蓝色数量bl,br,将i左端红色全不移动到最左端所需步数sl,最右端sr。

可以O(n)扫一边处理出来。

在枚举得到mid之后,就可一O(1)求出当前序列最优答案:

ans=sl[mid]-sl[l-1]-(rl[mid]-rl[l-1])*bl[l-1] + sr[mid+1]-sr[r+1]-(rr[mid+1]-rr[r+1])*br[r+1];

说一下左半部分,右半部分是类似的,sl[mid]-sl[l-1]是将[l,r]中所有红色移到序列最左端所需步数,而我们只需要将其移到枚举的端点的左端,所以要减去后边的东西。

如果把sl[mid]-sl[l-1]按递推式子拆开那么就很好理解了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define MAXN 2000010
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ma(x) memset(x,0,sizeof(x))
using namespace std;
char a[MAXN];
int n,T;
LL sl[MAXN],sr[MAXN],rl[MAXN],rr[MAXN],bl[MAXN],br[MAXN];
LL solve(int l,int r)
{
int L=l,R=r,mid,end=(rl[r]-rl[l-])>>;
while(L<=R)
{
mid=(L+R)>>;
if(rl[mid]-rl[l-]==end)break;
if(rl[mid]-rl[l-]>end) R=mid-;
if(rl[mid]-rl[l-]<end) L=mid+;
}
LL ans=sl[mid]-sl[l-]-(rl[mid]-rl[l-])*bl[l-]+sr[mid+]-sr[r+]-(rr[mid+]-rr[r+])*br[r+];
return sl[mid]-sl[l-]-(rl[mid]-rl[l-])*bl[l-]+
sr[mid+]-sr[r+]-(rr[mid+]-rr[r+])*br[r+];
}
signed main()
{
cin>>T;
while(T--)
{
n=;char te=getchar();
while(te!='B'&&te!='R')te=getchar();
while(te=='B'||te=='R'){a[++n]=te;te=getchar();}
for(int i=n+;i<=*n;i++)a[i]=a[i-n];
LL ans=0x7ffffffffffffff; rl[]=bl[]=sl[]=;
for(int i=;i<=n*;i++)
{
rl[i]=rl[i-],bl[i]=bl[i-];
sl[i]=sl[i-];
if(a[i]=='B')bl[i]++;
else rl[i]++,sl[i]+=bl[i];
}
rr[n*+]=br[n*+]=sr[n*+]=;
for(int i=n*;i>=;i--)
{
rr[i]=rr[i+],br[i]=br[i+];
sr[i]=sr[i+];
if(a[i]=='B')br[i]++;
else sr[i]+=br[i],rr[i]++;
}
for(int i=;i<=n;i++)
ans=min(ans,solve(i,i+n-));
cout<<ans<<endl;
}
}

O(n)正解:

用两个单调指针既可实现O(n),代码先留个坑。

HZOJ 寿司的更多相关文章

  1. 【BZOJ-4197】寿司晚宴 状压DP

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 694  Solved: 440[Submit][Status] ...

  2. [BZOJ4197][Noi2015]寿司晚宴

    4197: [Noi2015]寿司晚宴 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 412  Solved: 279[Submit][Status] ...

  3. BZOJ4197[NOI2005]寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

  4. HYSBZ 4197 寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

  5. BZOJ 4197: [Noi2015]寿司晚宴( dp )

    N^0.5以内的质数只有8个, dp(i, j, k)表示用了前i个大质数(>N^0.5), 2人选的质数(<=N^0.5)集合分别为j, k时的方案数. 转移时考虑当前的大质数p是给哪个 ...

  6. NOI2015 寿司晚宴

    今年NOI确实是在下输了.最近想把当时不会做的题都写一下. 题意 从2到n(500)这些数字中,选若干分给A,若干分给B,满足不存在:A的某个数和B的某个数的GCD不等于1. 对于寿司晚宴这题,标准解 ...

  7. bzoj 4199 [NOI2015]寿司晚宴

    Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被邀请参加了寿司晚宴. 在晚宴上,主办方为大家提供了 n−1 种不同 ...

  8. 【最大权闭合子图】bzoj4873 [Shoi2017]寿司餐厅

    4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 369  Solved: 256[Submit][Status ...

  9. BZOJ:4873: [Shoi2017]寿司餐厅

    4873: [Shoi2017]寿司餐厅 首先很开心在膜你赛的时候做了出来. 看到数据范围,看到不能dp,看到贡献去重后计算,咦,流? 那就容易了,转最大权闭合子图,每个区间建一个点,取了就一定要取他 ...

随机推荐

  1. python twisted 的定时调用带参的函数

    无参情况:lc = task.LoopingCall(fun)如果fun带有参数,可以使用functools.partial传递 (fun2 = partial(fun, param1,[...]) ...

  2. 解决Cesium1.50对gltf2.0/3dtiles数据读取的问题

    问题说明 Cesium 1.50(2018/10/01)版本打开3dtiles可能会出现加载不上导致渲染停止的错误. 错误说明为:RuntimeError: Unsupported glTF Exte ...

  3. Ubuntu18.04 修改IP地址、查看网关、防火墙

    1. Ubuntu18.04 修改IP地址 修改 sudo vim /etc/netplan/50-cloud-init.yaml文件 # This file is generated from in ...

  4. 数据库设计 ch.7

    数据库建设的基本规律 三分技术 七分管理 十二分基础数据 阶段 需求分析阶段 概念设计阶段 逻辑设计阶段 物理设计阶段 数据库实施阶段 数据库维护阶段 1 需求分析 2 概念设计 形成概念模型 3 逻 ...

  5. 轮播图js版&jQ版

    JS版轮播图 html部分和css部分自己任意定 主要构成: 1,一个固定的框 超出框的部分隐藏 2,几张图片float:left 3,下部下原点,点击切换,切换到不同的张都有红色显示 4,左右两个大 ...

  6. top进程命令

    top命令用来显示系统当前的进程状况. 格式:top [选项] 主要选项如下. d:指定更新的间隔,以秒计算. q:没有任何延迟的更新.如果使用者有超级用户,则top命令将会以最高的优先序执行. c: ...

  7. echarts 重新渲染(重新绘制,重新加载数据)等

  8. PHPStrom直接在编辑器打开php文件

    以下是自己配置PHP+Apache的开发环境,集成环境的话要换第二种方法(看个人配置):PHPStrom 如果希望直接在编辑器打开php文件,要做以下这几步配置. 第一种:非集成环境 1 2 3 第二 ...

  9. 如何让div处于body居中的状态

    <!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8&qu ...

  10. Leetcode874.Walking Robot Simulation模拟行走的机器人

    机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方.该机器人可以接收以下三种类型的命令: -2:向左转 90 度 -1:向右转 90 度 1 <= x <= 9:向 ...