Codeforces 868D Huge Strings - 位运算 - 暴力
You are given n strings s1, s2, ..., sn consisting of characters 0 and 1. m operations are performed, on each of them you concatenate two existing strings into a new one. On the i-th operation the concatenation saisbi is saved into a new string sn + i (the operations are numbered starting from 1). After each operation you need to find the maximum positive integer k such that all possible strings consisting of 0 and 1 of length k (there are 2k such strings) are substrings of the new string. If there is no such k, print 0.
The first line contains single integer n (1 ≤ n ≤ 100) — the number of strings. The next n lines contain strings s1, s2, ..., sn (1 ≤ |si| ≤ 100), one per line. The total length of strings is not greater than 100.
The next line contains single integer m (1 ≤ m ≤ 100) — the number of operations. m lines follow, each of them contains two integers aiabd bi (1 ≤ ai, bi ≤ n + i - 1) — the number of strings that are concatenated to form sn + i.
Print m lines, each should contain one integer — the answer to the question after the corresponding operation.
5
01
10
101
11111
0
3
1 2
6 5
4 4
1
2
0
On the first operation, a new string "0110" is created. For k = 1 the two possible binary strings of length k are "0" and "1", they are substrings of the new string. For k = 2 and greater there exist strings of length k that do not appear in this string (for k = 2 such string is "00"). So the answer is 1.
On the second operation the string "01100" is created. Now all strings of length k = 2 are present.
On the third operation the string "1111111111" is created. There is no zero, so the answer is 0.
题目大意 有n个01字符串,第i个操作是生成第n + i个字符串,方式是将两个已经存在的字符串拼接到一起,然后询问最大的k使得所有长度为k的01串都在这个串中出现过。
范围很吓人,意味着最大可能你需要判断2100个串是否存在(和同学组队开黑的时候被吓坏了。。懵逼了好久。),然而事实上。。答案都非常小。至少我没有找到一个超过10的。
另外注意到是拼接,所以串内部的情况不变,唯一增加新出现的子串的地方是拼接处,因为已经知道答案很小,就直接暴力就好了。
另外注意一个细节,就是用位运算弄得时候记得在开头加一个1,不然它会认为01和001是同一个串,但是101中并不存在串001。
(个人认为这道题的难点就在于估计答案范围,猜到很小就乱搞就好了,方法很多,什么记忆化搜索+二分也可以)
下面是答案会比较小的证明:(感谢我的学长idy002)
考虑长度为k的01串,在两个串进行合并的时候,两个串内部包含的本质不同的串是不变的,所以不会增加。因此新增加的子串一定是跨过交界处。
所以最多有(k - 1)个新增的本质不同的01串。再加上原本的包含为k的本质不同的01串的个数,可以列得不等式:

解不等式得到k不会超过11。
Code
/**
* Codeforces
* Problem#868D
* Accepted
* Time: 30ms
* Memory: 1700k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; #define limlen 15 typedef class String {
public:
string pre, suf;
boolean overflow;
int rt;
bitset<> mark; String():overflow(false) { }
}String; String operator + (String& a, String& b) {
String rt;
rt.overflow = a.overflow || b.overflow;
rt.mark = a.mark | b.mark;
if(!a.overflow) {
rt.pre = a.pre + b.pre;
if(rt.pre.length() > limlen)
rt.overflow = true, rt.pre.resize(limlen);
} else rt.pre = a.pre;
if(!b.overflow) {
rt.suf = a.suf + b.suf;
if(rt.suf.length() > limlen)
rt.overflow = true, rt.suf = rt.suf.substr(rt.suf.size() - limlen, rt.suf.size());
} else rt.suf = b.suf; string s = a.suf + b.pre;
for(int i = ; i < s.length(); i++)
for(int j = , t = ; j < limlen && i + j < s.length(); j++) {
t = (t << ) | (s[i + j] & );
rt.mark[t | ( << (j + ))] = ;
} int i;
for(rt.rt = ; ; rt.rt++) {
for(i = ; i < ( << rt.rt + ) && rt.mark[i | ( << rt.rt + )]; i++);
if(!rt.mark[i | ( << rt.rt + )])
break;
}
return rt;
} int n, m;
String strs[]; inline void init() {
cin >> n;
for(int i = ; i <= n; i++) {
cin >> strs[i].pre;
strs[i].suf = strs[i].pre;
strs[i].mark[] = ;
for(int j = ; j < strs[i].pre.length(); j++)
for(int k = , t = ; k < limlen && j + k < strs[i].pre.length(); k++) {
t = (t << ) | (strs[i].pre[j + k] & );
strs[i].mark[t | ( << (k + ))] = ;
}
}
} inline void solve() {
cin >> m;
for(int i = , a, b; i <= m; i++) {
cin >> a >> b;
strs[n + i] = strs[a] + strs[b];
cout << strs[n + i].rt << endl;
}
} int main() {
ios::sync_with_stdio(false), cin.tie(), cout.tie();
init();
solve();
return ;
}
Codeforces 868D Huge Strings - 位运算 - 暴力的更多相关文章
- [Codeforces Round #438][Codeforces 868D. Huge Strings]
题目链接:868D - Huge Strings 题目大意:有\(n\)个字符串,\(m\)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值.定义一个新串的价值\(k\)为:最大的\(k\) ...
- codeforces - 15C Industrial Nim(位运算+尼姆博弈)
C. Industrial Nim time limit per test 2 seconds memory limit per test 64 megabytes input standard in ...
- Codeforces 878A - Short Program(位运算)
原题链接:http://codeforces.com/problemset/problem/878/A 题意:给出n个位运算操作, 化简这些操作, 使化简后的操作次数不多于5步. 思路:我们可以对二进 ...
- Codeforces 868C Qualification Rounds - 位运算
Snark and Philip are preparing the problemset for the upcoming pre-qualification round for semi-quar ...
- POJ1753 Flip Game(位运算+暴力枚举)
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...
- CodeForces - 1230D(思维+位运算)
题意 https://vjudge.net/problem/CodeForces-1230D 要组建一个小组,要求小组中每个人都不比所有人强,当一个人懂得一个算法但是另一个不懂那么前者认为他比后者强. ...
- 【UVA】658 - It's not a Bug, it's a Feature!(隐式图 + 位运算)
这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 < ...
- Vus the Cossack and Strings(Codeforces Round #571 (Div. 2))(大佬的位运算实在是太强了!)
C. Vus the Cossack and Strings Vus the Cossack has two binary strings, that is, strings that consist ...
- CodeForces 282C(位运算)
C. XOR and OR time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
随机推荐
- idc指令相关
#按不同数据类型打印当前地址opcode print Byte(ea) print Word(ea) print Dword(ea)
- 题外话:Lua脚本语言存在的意义
纯属个人见解. 大致来说:c/c++执行效率高,游戏中一些性能敏感的复杂计算需要用c/c++来实现,防止游戏卡顿和低帧率.这些复杂计算包括战斗逻辑,复杂AI,骨骼动画蒙皮骨骼点的坐标计算等等.但c++ ...
- Linux基础(五) Shell函数
Shell 函数 linux shell 可以用户定义函数,然后在shell脚本中可以随便调用. shell中函数的定义格式如下: [ function ] funname [()] { action ...
- sqli-labs(十三)(hpp)
第二十九关 这关说的是有waf,其实只是模拟waf的场景,就是说waf处理的变量和后台程序接受的变量不一致. 考验的参数污染,具体可以参考其他文章关于HPP的解释. 先看源码吧: 输入?id=1&am ...
- 连接mysql && ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)
上一篇:mysql服务正在启动 mysql服务无法启动 && mysql启动脚本 mysql关闭脚本 此篇目编写一个核心目的: 1.mysql连接 先抛出一个问题 这是因为mysql服 ...
- Lambda表达式语法
基础语法:‘->’Lambda操作符* 左侧:Lambda表达式的参数列表 对应接口中方法中的参数列表中的参数(比如nice1中MyPredict这个接口中的方法)* 右侧:Lambda表达式中 ...
- 《大话设计模式》c++实现 代理模式
代理模式 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 介绍 意图:为其 ...
- Yii2缓存依赖
- hdu5422 最大表示法+KMP
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio&g ...
- Java输入输出流(IO)-----文件类File详解
1.java.io.File类简介 凡是与输入.输出相关的类.接口等都定义在java.io包下 File是一个类,可以有构造器创建其对象.此对象对应着一个文件(.txt .avi .doc .p ...