题目传送门

题解:

id[ i ][ j ] 代表的是在第j个位置之后的第i个字符的位置在哪里。

dp[ i ][ j ][ k ] 代表的是 第一个串匹配到第i个位置, 第二个串匹配到第j个位置, 第三个串匹配到第k个位置之后,最后面一个字符的位置在哪里。

如果题目只询问一次,那么应该很容易想到n^3的写法。

for(int i = ; i <= n1; ++i){
for(int j = ; j <= n2; ++j){
for(int k = ; k <= n3; ++k){
if(i+j+k) dp[i][j][k] = n + ;
if(i) dp[i][j][k] = min(dp[i][j][k], id[ss[][i]-'a'][dp[i-][j][k]]);
if(j) dp[i][j][k] = min(dp[i][j][k], id[ss[][j]-'a'][dp[i][j-][k]]);
if(k) dp[i][j][k] = min(dp[i][j][k], id[ss[][k]-'a'][dp[i][j][k-]]);
}
}

但是,在一共有q次询问的前提下,肯定是不能每次询问都直接n^3的暴力得到的。

现在假如我们知道了 dp[3][4][6]的信息。

现在在第3个串后面加了一个字符,也就是说我们需要知道dp[3][4][7]的信息。

可以观察2遍的 n^3中的结果。

其中 for  i  from 0 to 3

    for j  from 0 to 4

      for k from 0 to 6 的dp值和前面没有任何不同。

唯一区别的是 :

  for i from 0 to 3

    for j from 0 to 4

      for k from 7 to 7 的dp值会发生变化。

所以我们只需要跑一边

   for k from 7 to 7

    for i from 0 to 3

      for k from  0 to  4的dp值,更新这一块的dp值就好了。

如果 i + 1了 或者 j + 1了也是一样的道理。

所以每次更新所跑的值都是 len ^ 2。

最后的复杂度就是 q * len ^ 2. (len <= 250)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod = (int)1e9+;
const int N = 1e5 + ;
char s[N];
int id[][N];
int dp[][][];
char ss[][N];
void Ac(){
int n, m;
scanf("%d%d", &n, &m);
scanf("%s", s+);
for(int i = ; i < ; ++i)
id[i][n+] = n+;
for(int j = n; j >= ; --j){
for(int i = ; i < ; ++i){
id[i][j] = id[i][j+];
}
if(j < n) id[s[j+]-'a'][j] = j+;
}
int l1, l2, l3, n1, n2, n3;
l1 = l2 = l3 = n1 = n2 = n3 = ;
char op[];
int t;
for(int _ = ; _ <= m; ++_){
scanf("%s", op);
if(op[] == '+'){
scanf("%d%s", &t, op);
if(t == ) {
++n1; ss[][n1] = op[];
for(int i = n1; i <= n1; ++i){
for(int j = ; j <= l2; ++j){
for(int k = ; k <= l3; ++k){
if(i+j+k) dp[i][j][k] = n + ;
if(i) dp[i][j][k] = min(dp[i][j][k], id[ss[][i]-'a'][dp[i-][j][k]]);
if(j) dp[i][j][k] = min(dp[i][j][k], id[ss[][j]-'a'][dp[i][j-][k]]);
if(k) dp[i][j][k] = min(dp[i][j][k], id[ss[][k]-'a'][dp[i][j][k-]]);
}
}
}
}
if(t == ) {
++n2; ss[][n2] = op[];
for(int j = n2; j <= n2; ++j){
for(int i = ; i <= l1; ++i){
for(int k = ; k <= l3; ++k){
if(i+j+k) dp[i][j][k] = n + ;
if(i) dp[i][j][k] = min(dp[i][j][k], id[ss[][i]-'a'][dp[i-][j][k]]);
if(j) dp[i][j][k] = min(dp[i][j][k], id[ss[][j]-'a'][dp[i][j-][k]]);
if(k) dp[i][j][k] = min(dp[i][j][k], id[ss[][k]-'a'][dp[i][j][k-]]);
}
}
}
}
if(t == ) {
++n3; ss[][n3] = op[];
for(int k = n3; k <= n3; ++k){
for(int i = ; i <= l1; ++i){
for(int j = ; j <= l2; ++j){
if(i+j+k) dp[i][j][k] = n + ;
if(i) dp[i][j][k] = min(dp[i][j][k], id[ss[][i]-'a'][dp[i-][j][k]]);
if(j) dp[i][j][k] = min(dp[i][j][k], id[ss[][j]-'a'][dp[i][j-][k]]);
if(k) dp[i][j][k] = min(dp[i][j][k], id[ss[][k]-'a'][dp[i][j][k-]]);
}
}
}
}
}
else {
scanf("%d", &t);
if(t == ) --n1;
if(t == ) --n2;
if(t == ) --n3;
}
l1 = n1; l2 = n2; l3 = n3;
if(dp[l1][l2][l3] != n + ) puts("YES");
else puts("NO");
}
}
int main(){
Ac();
return ;
}
/*
6 8
abdabc
+ 1 a
+ 1 d
+ 2 b
+ 2 c
*/

CodeForces - 1150 D Three Religions的更多相关文章

  1. CF 1150 D Three Religions——序列自动机优化DP

    题目:http://codeforces.com/contest/1150/problem/D 老是想着枚举当前在给定字符串的哪个位置,以此来转移. 所以想对三个串分别建 trie 树,然后求出三个t ...

  2. Codeforces 1149 B - Three Religions

    B - Three Religions 思路:dp dp[i][j][k]:a的前i个和b的前j个和c的前k个能构成的最前面的位置 删字符时状态不用改变,加字符时只会改变1*250*250个状态 代码 ...

  3. Codeforces Round #556 (Div. 2) - D. Three Religions(动态规划)

    Problem  Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 3000 mSec Problem Descripti ...

  4. Codeforces Round #556 (Div. 2) D. Three Religions 题解 动态规划

    题目链接:http://codeforces.com/contest/1150/problem/D 题目大意: 你有一个参考串 s 和三个装载字符串的容器 vec[0..2] ,然后还有 q 次操作, ...

  5. codeforces#1150D. Three Religions(dp+序列自动机)

    题目链接: https://codeforces.com/contest/1150/problem/D 题意: 给出长度为$n$的字符串,和$q$次询问 每次询问是,给$x$宗教增加一个字符$key$ ...

  6. Three Religions CodeForces - 1149B (字符串,dp)

    大意: 给定字符串S, 要求维护三个串, 支持在每个串末尾添加或删除字符, 询问S是否能找到三个不相交的子序列等于三个串. 暴力DP, 若不考虑动态维护的话, 可以直接$O(len^3)$处理出最少需 ...

  7. Codeforces 1050D Three Religions (dp+序列自动机)

    题意: 给一个1e5的串str,然后有三个起始空串,不超过1000次操作,对三个字符串的一个尾部加一个字符或者减一个字符,保证每个字符不会超过250 每次操作之后询问你这三个串是不是可以组成str的子 ...

  8. Codeforces Educational Codeforces Round 5 C. The Labyrinth 带权并查集

    C. The Labyrinth 题目连接: http://www.codeforces.com/contest/616/problem/C Description You are given a r ...

  9. Educational Codeforces Round 5

    616A - Comparing Two Long Integers    20171121 直接暴力莽就好了...没什么好说的 #include<stdlib.h> #include&l ...

随机推荐

  1. 【iOS】Apple Mach-O Linker Error Linker command failed with exit code 1

    又遇到了这个问题,貌似之前遇到过……如图所示: 解决方法寻找中………… 在 Stack Overflow 找到了解决方法,如下: 参考链接:Apple Mach-O Linker Error

  2. Iterator-Java

    在Java中,Iterator的作用就是为了方便处理集合中的元素.例如获取和删除集合中的元素. 在JDK8,Iterator接口提供了如下方法: 迭代器Iterator最基本的两个方法是next()和 ...

  3. 技巧:结合Zabbix与SNMP监控嵌入式设备

    在如何利用Zabbix监控网络设备三篇文章的前两篇中,我们介绍了如何通过Zabbix代理监控网络设备.但有些设备无法安装Zabbix代理,需要采用其他方法监控.需要考虑无法安装软件的嵌入式设备或应用程 ...

  4. Kubernetes容器集群管理环境 - 完整部署(上篇)

    Kubernetes(通常称为"K8S")是Google开源的容器集群管理系统.其设计目标是在主机集群之间提供一个能够自动化部署.可拓展.应用容器可运营的平台.Kubernetes ...

  5. 自定义itemCheckView

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  6. 用命令将本地jar包导入到本地maven仓库

    [**前情提要**]在日常开发过程中,我们总是不可避免的需要依赖某些不在中央仓库,同时也不在本地仓库中的jar包,这是我们就需要使用命令行将需要导入本地仓库中的jar包导入本地仓库,使得项目依赖本地仓 ...

  7. python 闭包,装饰器,random,os,sys,shutil,shelve,ConfigParser,hashlib模块

    闭包 def make_arerage(): l1 = [] def average(price): l1.append(price) total = sum(l1) return total/len ...

  8. 如何调教你的博客Episode1——修改整体样式

    如图所示,这是你刚刚注册的博客园博客,让我们开始一步步修改它. 1.写入自适应代码 html,body{ height:100%; border:; margin:; padding:; } body ...

  9. Throughput Controller

    吞吐量控制器(Throughput Controller)介绍 作用:控制其子节点的执行次数与负载比例分配 Total Executions: 整个测试计划中的总执行次数 Percent Execut ...

  10. Nginx 502 Bad Gateway 错误的解决方法

    502 bad gateway 的解决方法 通用配置 proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; # ...