[CF163E]e-Government
题目
点这里看题目。
分析
首先,我们不需要真的从 AC 自动机中把串删掉。由于我们计算贡献和,我们只需要在 AC 自动机上,把已经删除的串的贡献抹掉就可以了。
接着考虑询问。这是一个很基础的问题,一般我们会在 AC 自动机上面处理出每个状态的贡献和,并且将询问的字符串在 AC 自动机上面跑一跑,答案就是经过的状态的贡献和的贡献和。
现在贡献是动态的,我们的贡献和也变成了动态的。不过,由于贡献和本质上就是\(fail\)树上到根的路径的贡献和,因此我们可以对\(fail\)树进行树链剖分,修改就是单点修改,查询就查询到根的贡献和。这样就可以用 BIT 来维护一下区间和。
另一种更简单的方法是,在一个点上改贡献的时候,有且仅有其子树内的点会被影响,因此我们用 BIT 维护差分,每次修改就是将子树内的贡献 +1 ,查询就直接查询。这样做就少了一个\(\log_2n\)。
这两种方法体现了两种不同的思想——统计贡献和维护贡献;两者需要具体问题具体分析再选择使用。
代码
#include <cstdio>
#include <iostream>
using namespace std;
#define Tour( c ) for( int c = 0 ; c < 26 ; c ++ )
#define up( x ) ( x += ( x & ( -x ) ) )
#define down( x ) ( x -= ( x & ( -x ) ) )
typedef long long LL;
const int MAXN = 1e5 + 5, MAXL = 1e6 + 5;
template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
}
template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
}
struct edge
{
int to, nxt;
}Graph[MAXL << 1];
LL BIT[MAXL];
int head[MAXL], pos[MAXL], siz[MAXL];
int ch[MAXL][26], fail[MAXL], q[MAXL];
int ed[MAXN];
int N, K, tot, cnt, ID;
char S[MAXL];
bool inside[MAXN];
void update( int x, const int v ) { for( ; x <= ID ; up( x ) ) BIT[x] += v; }
LL getSum( int x ) { LL ret = 0; for( ; x ; down( x ) ) ret += BIT[x]; return ret; }
void update( const int x ) { if( ! inside[x] ) inside[x] = true, update( pos[ed[x]], 1 ), update( pos[ed[x]] + siz[ed[x]], -1 ); }
void remove( const int x ) { if( inside[x] ) inside[x] = false, update( pos[ed[x]], -1 ), update( pos[ed[x]] + siz[ed[x]], 1 ); }
void addEdge( const int from, const int to )
{
Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
head[from] = cnt;
}
void insert( const int rnk )
{
int p = 0, id;
for( int i = 1 ; S[i] ; i ++ )
{
id = S[i] - 'a';
if( ! ch[p][id] ) ch[p][id] = ++ tot;
p = ch[p][id];
}
ed[rnk] = p;
}
void init()
{
int h = 1, t = 0, u, v;
Tour( i ) if( ch[0][i] ) q[++ t] = ch[0][i];
while( h <= t )
{
u = q[h ++];
Tour( i )
{
if( v = ch[u][i] ) fail[v] = ch[fail[u]][i], q[++ t] = v;
else ch[u][i] = ch[fail[u]][i];
}
addEdge( fail[u], u );
}
}
void DFS( const int u )
{
siz[u] = 1, pos[u] = ++ ID;
for( int i = head[u], v ; i ; i = Graph[i].nxt )
DFS( v = Graph[i].to ), siz[u] += siz[v];
}
int main()
{
LL ans; int id, p;
read( N ), read( K );
for( int i = 1 ; i <= K ; i ++ ) scanf( "%s", S + 1 ), insert( i );
init();
DFS( 0 );
for( int i = 1 ; i <= K ; i ++ ) update( i );
while( N -- )
{
scanf( "%s", S );
if( S[0] == '?' )
{
ans = p = 0;
for( int i = 1 ; S[i] ; i ++ )
p = ch[p][S[i] - 'a'],
ans += getSum( pos[p] );
write( ans ), putchar( '\n' );
}
else if( S[0] == '+' ) sscanf( S + 1, "%d", &id ), update( id );
else sscanf( S + 1, "%d", &id ), remove( id );
}
return 0;
}
[CF163E]e-Government的更多相关文章
- youths |government|some
N-COUNT (新闻用语,尤指惹麻烦的)青年,小伙子Journalists often refer to young men as youths, especially when they are ...
- 题解-CF163E e-Government
题面 CF163E e-Government 给 \(n\) 个字符串 \(s_i\) 和 \(q\) 个询问,刚开始字符串都服役.每次操作将集合中的一个字符串设为退役或服役,或查询与文本串 \(S_ ...
- 【CF163E 】e-Government
题目 两个\(log\)的树状数组套树剖? 我们对于给出的\(n\)个模式串建立\(AC\)自动机,之后对于每一个询问串直接丢上去匹配 如果这里是暴力的话,我们直接一路跳\(fail\)累加作为结束位 ...
- 【NLP】Python NLTK获取文本语料和词汇资源
Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...
- UVA-146 ID Codes
It is 2084 and the year of Big Brother has finally arrived, albeit a century late. In order to exerc ...
- 2011奥斯卡最佳纪录片《监守自盗(Inside Job)》小结
影片探讨了2008年金融危机产生的原因. 美国忽略1933年的旧法律,立新法,以放松金融监管. 投资银行被允许更高的杠杆率,33:1,也就是说,投资物跌价3%就会导致破产. 投资银行放贷,但是转手将贷 ...
- 微服务(Microservices)—Martin Fowler【翻译】
本文转载自:http://www.cnblogs.com/liuning8023/p/4493156.html -------------------------------------------- ...
- 资源描述结构(Resource Description Framework,RDF)
资源描述框架(Resource Description Framework),一种用于描述Web资源的标记语言.RDF是一个处理元数据的XML(标准通用标记语言的子集)应用,所谓元数据,就是" ...
- 学券制(教育券、school voucher)
美国「学券制」是怎样的一种制度?它为什么是共和党的执政政策?它在美国及其它地区有实施吗?效果如何?能否在保证公平的同时,通过市场提高教育质量? 作者:冉筱韬链接:https://www.zhihu.c ...
随机推荐
- java 字符串转为list
List<String> idList = Arrays.asList(irIds.split(","));
- 201771010117马兴德 实验二 Java基本程序设计(1)
实验二 Java基本程序设计(1) 第一部分 理论知识的学习. 第三章Java基本程序设计结构 1 基本知识: (1)标识符:标识符由字母.下划线.美元符号和数字组成,且第一个符号不能为数字 ...
- E. Alternating Tree 树点分治|树形DP
题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1) 注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...
- es6的数组操作
//foreach 迭代 var arr = [1, 2, 3]; var sum = 0; arr.forEach(function(value, index, array) { console.l ...
- DBCP连接池和事物
工具类案例 public static final String DRIVER = "com.mysql.jdbc.Driver"; public static final Str ...
- ASP.NET Core Blazor Webassembly 之 组件
关于组件 现在前端几大轮子全面组件化.组件让我们可以对常用的功能进行封装,以便复用.组件这东西对于搞.NET的同学其实并不陌生,以前ASP.NET WebForm的用户控件其实也是一种组件.它封装ht ...
- [Firefox附加组件]0001.入门
Firefox 火狐浏览器,拥有最快.最安全的上网体验,并且火狐拥有超过一万个的 扩展(add-ons),提供各种不同的扩展功能,您可以简单的下载.安装这些扩展以增强您的火狐功能,帮助您更好.更个性化 ...
- 删除节点与插入节点 & innerHTML
1.测试removeChild()方法: 删除节点dom9.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" &q ...
- 跨域解决方案 - 跨域资源共享cors
目录 1. cors 介绍 2. 原理 3. cors 解决跨域 4. 自定义HTTP 头部字段解决跨域 5. 代码演示 5. 参考链接 1. cors 介绍 cors 说的是一个机制,其实相当于一个 ...
- Java实现 LeetCode 752 打开转盘锁(暴力)
752. 打开转盘锁 你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' .每个拨轮可以自由旋 ...