CF1037G A Game on Strings Sol
有趣题。
首先"分成若干个互不相干的子串"是子游戏的定义,可以用 SG 函数处理。
然而接下来试着打了半个多小时的表,没有找到任何规律。
但是发现 SG 函数的状态转移是很简单的。一般 SG 函数难以优化的点在于 \(\text{MEX}\) 操作不太平易近人,这道题中让你取 \(\text{MEX}\) 的只有 26 个数完全可以暴力去做。
进一步地,我们想到这道题中能够成为”子游戏“的子区间是很有限的,对于删去某个字符形成的若干段字符串,只有这些串的前缀后缀是需要计算 SG 函数的。
所以我们只需要按照这些串的长度从小到大计算 SG 值即可。
然而事情并不是那么美好,如果没注意好实现细节直接拿 std::map 维护 SG 值会多 \(\log\),复杂度达到了 \(O(n|\Sigma|^2\log n)\)。
于是重构了一遍代码,考虑按右端点和串长度双关键字的顺序计算这些区间,并且用合适的数组替换掉数据结构,复杂度 \(O(n|\Sigma|^2)\)。
这道题实现还是很有技巧的,应该要有 implementation 的标签。
#include <bits/stdc++.h>
using namespace std;
const int N=100003;
char s[N];
int n,q;
int a[N][26],fa[N][26];
int b[N][26],fb[N][26];
int f[N],cur[26];
int calc(int l,int r){
if(l>r) return 0;
unsigned int st=0;
for(int c=0;c<26;++c){
int pl=a[l][c],pr=b[r][c];
if(pl<=pr) st|=1u<<(f[pl]^f[pr]^fa[l][c]^fb[r][c]);
}
return __builtin_ctz(~st);
}
int stk[26];
int main(){
scanf("%s",s+1);
n=strlen(s+1);
for(int c=0;c<26;++c) a[n+1][c]=n+1;
for(int i=n;i;--i){
memcpy(a[i],a[i+1],104);
a[i][s[i]-97]=i;
}
for(int c=0;c<26;++c) b[0][c]=0;
for(int i=1;i<=n;++i){
memcpy(b[i],b[i-1],104);
b[i][s[i]-97]=i;
}
for(int c=0;c<26;++c) stk[c]=c;
for(int i=1;i<=n;++i){
int c=s[i]-97;
f[i]=f[cur[c]]^fb[i-1][c];cur[c]=i;
sort(stk,stk+26,[&](int x,int y){return b[i][x]>b[i][y];});
for(int t=0;t<26;++t){
int o=stk[t];
if(b[i][o]<i) fb[i][o]=calc(b[i][o]+1,i);
}
if(i<n){
int cc=s[i+1]-97;
for(int j=i;j>cur[cc];--j) fa[j][cc]=calc(j,i);
}
}
scanf("%d",&q);
while(q--){
int l,r;
scanf("%d%d",&l,&r);
if(calc(l,r)) puts("Alice");
else puts("Bob");
}
return 0;
}
CF1037G A Game on Strings Sol的更多相关文章
- 区块链之智能合约 solidity踩坑 --上篇
概述 最近在写合约时遇到一些坑,做一下总结: 介绍主要分一下三个方面: 对区块链的简单描述 结合业务场景,编写简单智能合约,时遇到的坑(上篇) assembly 的使用说明(下篇) 正文 进入正题之前 ...
- solidity如何拼接字符串?
当你开始学习使用solidity开发以太坊智能合约之后,很快你会碰到一个问题: 一.在solidity中该如何拼接字符串? 可能你已经试过了,下面的代码试图把两个字符串使用相加的运算符连接起来,但是这 ...
- 以太坊和IPFS如何存储数据
如何将JSON文件存储在IPFS上,并使用Oraclize访问智能合约中的数据呢? 以太坊是一个成熟的区块链,使开发人员能够创建智能合约,在区块链上执行的程序可以由交易触发.人们经常将区块链称为数据库 ...
- [Leetcode][Python]43: Multiply Strings
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 43: Multiply Stringshttps://leetcode.co ...
- Hacker Rank: Two Strings - thinking in C# 15+ ways
March 18, 2016 Problem statement: https://www.hackerrank.com/challenges/two-strings/submissions/code ...
- StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing the strings?
StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing t ...
- Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- [LeetCode] Add Strings 字符串相加
Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...
- [LeetCode] Encode and Decode Strings 加码解码字符串
Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...
- [LeetCode] Group Shifted Strings 群组偏移字符串
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
随机推荐
- 入门级java开发环境的配置安装
为了能够在计算机上开发Java程序和运行Java程序,就需要在Windows操作系统上配置Java开发环境. 首先,安装JDK: 1.在Oracle官网上下载JavaSE: 2.在Download下载 ...
- 第一天1h
//摄氏度和华氏度之间的换算//20211120//ZhangWenjing#include<stdio.h>int main(void){ int f = 0; int c = 0; s ...
- 帝国CMS 登录后跳转ecmsadmin.php 白页 多个解决方案
帝国CMS 6.6 版本, 运维的网站查询除了问题, 把网站数据库和整体网站拷贝到本地服务器, 配置好 e/config/config.php 和 e/class/config.php 两个目录 ...
- 如何通过dump文件定位崩溃,解决问题
1.dump文件是附加堆栈信息的存储文件的简称,文件扩展名".dmp",通过dump文件我们可以得到程序运行某一时刻的堆栈数据.2.当程序意外崩溃后,通常程序会立即中断运行,拿到这 ...
- CH573 CH582 CH579蓝牙从机(peripheral)例程讲解六(蓝牙设置白名单)
蓝牙从机设置白名单,可以只扫描应答(白名单中列出的)设备,只允许(白名单中列出的)设备连接. 蓝牙主机设置白名单,可以只扫描.连接特定的蓝牙设备(白名单中列出的). 一.蓝牙从机白名单设置有关的函数介 ...
- ssh反向代理树莓派+motion,实现公网远程视频监控
注意:本文公网远程监控部分需要借助有公网IP的云服务器进行ssh反向代理. 一.借助motion实现内网的视频监控 准备 插上摄像头,然后输入ls /dev/video*命令检查是否识别了摄像头 安装 ...
- DB2生成UUID, CONCAT (HEX (RAND ()), HEX (RAND ())) 排坑
DB2中没有提供生成UUID的方法,一般我们常用的是CONCAT (HEX (RAND ()), HEX (RAND ())) 来生成UUID,但是大量生成的时候会产生重复数据,导致我们的唯一索引报错 ...
- https传输流程(加密方式、证书、传输安全)
http的缺点 http的数据是明文传输 如果用明文传输 很容易被第三方获取到传输的数据 因此我们一般要在网络传输过程中对数据进行加密 常见的加密方式 对称加密 秘钥key 待加密数据data a和b ...
- Java8-聚合操作
Java聚合操作(Aggregate Operations)是对一堆数据进行处理的新的操作方法,我们知道,如果想对一堆数据进行处理,比如一个List对象中的数据进行处理,传统的操作就是遍历List数据 ...
- egret 当前运行环境
if(egret.Capabilities.runtimeType == egret.RuntimeType.WXGAME){}