题意:

题目描述较为繁琐,vj上有翻译版:点这里

思路:

首先可以确定的是,如果玩家 \(2\) 的策略是最优策略,那么其一定会选形如 \(01/10\) 这样的串。因为玩家 \(2\) 必须要选至少一个 \(1\) ,那么一定我们希望每次尽量少用 \(1\) 并且多消耗玩家1需要的 \(0\),这样才可以使得可以撑更多的回合,更优。

又发现,我们如果想让玩家 \(1\) 获胜,那么必然其比玩家 \(2\) 多玩了 \(1\) 轮。考虑玩家 \(2\) 输了最后会出现怎样的局面:

显然有两种情况。第一种是所有 \(1\) 都被拿完了,并且局面还能保证玩家 \(1\) 至少还能玩 \(1\) 轮,第二种是最后还剩一个 \(1\) ,但是没有其他任何元素了,那么此时玩家 \(2\) 也无法胜利。

所以我们考虑记 \(cnt_{0/1}\) 表示序列中 \(0/1\) 的个数,先考虑上述第一种情况,此时玩家 \(2\) 拿完了所有 \(1\) ,并且按照最优策略。那么玩家 \(2\) 就拿了 \(cnt_1\) 个 \(1\) 和 \(0\),此时若要满足玩家 \(1\) 能至少比玩家 \(2\) 多玩一轮,则一定,其拿了 \(2\times(cnt_1 + 1)\) 个 \(0\)。也就等价说明了,要满足玩家 \(1\) 必胜,一定要满足:

\[cnt_0\geq3\times cnt_1+2
\]

什么,你说怎么保证每一次玩家 \(1\) 都可以行动?很简单,我们换一个视角思考这个问题,考虑我们现在已经有了 \(cnt_1\) 个 \(1\),我们将所有的 \(0\) 分配到任意的两个 \(1\) 之间,因为至少有 \(3\times cnt_1+2\) 个 \(0\) 则所有的分配情况下都一定会存在至少有 \(3\) 个连续(相邻)的 \(0\) \((cnt_1>0)\) 的方案,所以不用担心不够用,并且每一轮玩家 \(1\) 和玩家 \(2\) 都进行了游戏后,这个不等式是依然成立的,所以每一次都可以保证玩家 \(1\) 可以行动。

又很显然的,当上述不等式取等时,我们的必胜策略已经到极限了,再让 \(cnt_0\) 变小就无法保证玩家 \(1\) 必胜了,所以上述不等式是充要的。

用同样的分析方法,可以得出如果要产生第二种必胜结局,则一定:

\[cnt_0=3\times cnt_1-1
\]

证明思路同上,略。

现在考虑统计答案,我们试着枚举区间左端点 \(r\),那么我们现在需要知道的就是有多少个 \(l\) 是合法的。显然一个合法的 \(l\) 需要满足的充要条件(情况1)是:

\[(cntr_0-cntl_0)\geq3\times(cntr_1-cntl_1) + 2
\]

我们试着对式子进行变换:

\[(cntr_0-3\times cntr_1)-2\geq cntl_0 - 3\times cntl_1
\]

你发不等式现左边括号中的内容与不等式右边是同构的。所以我们定义函数 \(f(i)=cnti_0-3\times cnti_1\) ,所以不等式变为:

\[f(r) - 2\geq f(l)
\]

那么我们现在只需要找出这样的 \(l\) ,如果我们暴力枚举的话,复杂度是 \(O(n^2)\) 的,显然无法通过本题,但你发现这是一个求区间 \([1,r-1]\) 中的合法下标的问题,既然是区间问题,我们可以考虑建立一颗树状数组来解决这个问题,以减少对前面区间的重复遍历。但是这不是一般的树状数组。事实上,我们应当建立一颗值域树状数组,也就是下标为 \(f(x)\) 中存的东西。并且每次遍历完 \(r\) 后,都需要将树状数组中 \(f(r)\) 的部分加\(1\),即遍历到了多一个值为 \(f(r)\) 的下标 \(r\) ,方便给后面的数计算。

对于情况二是同理的,只是需要注意的是,情况二是等号,所以需要减去小于 \(f(r) + 1\) 的部分的贡献(这么说有点抽象,直接看代码可能更好理解)。

Code:

注意上述分析中 \(f(x)\) 可能为负数,所以需要加一个偏移量来保证树状数组下标的非负。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
inline int read(){
char c=getchar();bool f=0;int x=0;
while(c > '9' || c < '0') f|=c=='-',c=getchar();
while(c >= '0'&&c <= '9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
if(f) x=-x;return x;
} const int M = 4e6 + 10,N = 3e5 + 10;
char s[N];
int n,tree[M],pre[N],up_limit;
int lowbit(int x){return x & (-x);} void add(int x, int k){
for(;x <= up_limit;x += lowbit(x))
tree[x] += k;
} LL query(int x){
LL res = 0;
for(;x;x -= lowbit(x))
res += tree[x];
return res;
} int main()
{
n = read();
scanf("%s",s + 1);
LL ans = 0;
up_limit = 3e6 + 10;
for(int i = 1;i <= n;++i)
{
pre[i] = pre[i - 1] + (s[i] == '0' ? 1 : -3);
}
for(int i = 0;i <= n;++i) pre[i] += 3 * n + 5; add(pre[0],1);
for(int i = 1;i <= n;++i)
{
ans += query(pre[i] - 2) + (query(pre[i] + 1) - query(pre[i]));
add(pre[i],1);
} printf("%lld",ans);
return 0;
}

CF2070E(edu.175) Game with Binary String 题解的更多相关文章

  1. Codeforces #698 (Div. 2) E. Nezzar and Binary String 题解

    中文题意: 给你两个长度为 \(n\) 的01串 \(s,f,\)有 \(q\) 次询问. 每次询问有区间 \([\ l,r\ ]\) ,如果 \([\ l,r\ ]\) 同时包含\(0\)和\(1\ ...

  2. Binary String Matching(kmp+str)

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  3. Codeforces 862D. Mahmoud and Ehab and the binary string (二分)

    题目链接:Mahmoud and Ehab and the binary string 题意: 一道交互题,首先给出一个字符串的长度l.现在让你进行提问(最多15次),每次提问提出一个字符串,会返回这 ...

  4. Codeforces1107E Vasya and Binary String 记忆化dp

    Codeforces1107E 记忆化dp E. Vasya and Binary String Description: Vasya has a string \(s\) of length \(n ...

  5. Codeforces Round #598 (Div. 3) D. Binary String Minimizing 贪心

    D. Binary String Minimizing You are given a binary string of length n (i. e. a string consisting of ...

  6. Educational Codeforces Round 94 (Rated for Div. 2) String Similarity、RPG Protagonist、Binary String Reconstruction、Zigzags 思维

    题目链接:String Similarity 题意: 首先题目定义了两个串的相似(串的构成是0.1),如果两个串存在对于一个下标k,它们的值一样,那么这两个串就相似 然后题目给你一个长度为2n-1的串 ...

  7. Binary String Matching

    问题 B: Binary String Matching 时间限制: 3 Sec  内存限制: 128 MB提交: 4  解决: 2[提交][状态][讨论版] 题目描述 Given two strin ...

  8. NYOJ之Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述     Given two strings A and B, whose a ...

  9. ACM Binary String Matching

    Binary String Matching 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 Given two strings A and B, whose alp ...

  10. encode_json 会对给定的Perl的数据结构转换为一个UTF-8 encoded, binary string.

    use JSON qw/encode_json decode_json/ ; use Encode; my $data = [ { 'name' => 'Ken' , 'age' => 1 ...

随机推荐

  1. codeup之日期差值

    description 有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天. Input 有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD Outp ...

  2. codeup之输出梯形

    Description 输入一个高度h,输出一个高为h,上底边为h的梯形. Input 一个整数h(1<=h<=1000). Output h所对应的梯形. Sample Input Co ...

  3. [Redis] Redis (7) 连接与会话管理

    序:文由 因今日排查问题,发现微服务因 ERR max number of clients reached (已达到客户端的最大数量) redis异常,而导致服务在健康检测时未通过,进而导致高频宕机. ...

  4. 【公众号搬运】React-Native开发鸿蒙NEXT(4)

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  5. JS/Jquery检查网络路径文件是否存在

    var url='网络文件路径'; var isExists; $.ajax(url, { type: 'HEAD', dataType: 'text', async: false, success: ...

  6. RBMQ案例四:路由模式

    使仅订阅消息的子集成为可能.例如,我们将能够仅将关键错误消息定向到日志文件(以节省磁盘空间),同时仍然能够在控制台上打印所有日志消息.   通过路由来匹配对应的消息 一.消息发布端 #!/usr/bi ...

  7. Java泛型<T> T与T的用法

             泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的 ...

  8. update 批量修改sql 记录

    update_table 是要修改的表 join_table 是关联另一张表来修改update_table表的字段 update update_table set id= tmp.id from jo ...

  9. 使用Roslyn运行C#脚本时如何引用程序集

    使用Roslyn的CSharpScript类运行C#脚本时,会默认包含一部分程序集,默认包含的程序集引用可以直接使用,而其他程序集则需要额外提供引用.本文简单描述了使用Roslyn的CSharpScr ...

  10. 你应该懂得AI大模型(十二)之 QLoRA

    一.显存和算力 1. 基本概念 显存 (Memory) 定义:GPU 用于临时存储数据的高速内存,类似于计算机的 RAM. 作用: 存储模型权重.中间激活值.梯度和优化器状态. 数据在显存与 GPU ...