题目

  点这里看题目。

分析

  首先,我们不需要真的从 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的更多相关文章

  1. youths |government|some

    N-COUNT (新闻用语,尤指惹麻烦的)青年,小伙子Journalists often refer to young men as youths, especially when they are ...

  2. 题解-CF163E e-Government

    题面 CF163E e-Government 给 \(n\) 个字符串 \(s_i\) 和 \(q\) 个询问,刚开始字符串都服役.每次操作将集合中的一个字符串设为退役或服役,或查询与文本串 \(S_ ...

  3. 【CF163E 】e-Government

    题目 两个\(log\)的树状数组套树剖? 我们对于给出的\(n\)个模式串建立\(AC\)自动机,之后对于每一个询问串直接丢上去匹配 如果这里是暴力的话,我们直接一路跳\(fail\)累加作为结束位 ...

  4. 【NLP】Python NLTK获取文本语料和词汇资源

    Python NLTK 获取文本语料和词汇资源 作者:白宁超 2016年11月7日13:15:24 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集 ...

  5. UVA-146 ID Codes

    It is 2084 and the year of Big Brother has finally arrived, albeit a century late. In order to exerc ...

  6. 2011奥斯卡最佳纪录片《监守自盗(Inside Job)》小结

    影片探讨了2008年金融危机产生的原因. 美国忽略1933年的旧法律,立新法,以放松金融监管. 投资银行被允许更高的杠杆率,33:1,也就是说,投资物跌价3%就会导致破产. 投资银行放贷,但是转手将贷 ...

  7. 微服务(Microservices)—Martin Fowler【翻译】

    本文转载自:http://www.cnblogs.com/liuning8023/p/4493156.html -------------------------------------------- ...

  8. 资源描述结构(Resource Description Framework,RDF)

    资源描述框架(Resource Description Framework),一种用于描述Web资源的标记语言.RDF是一个处理元数据的XML(标准通用标记语言的子集)应用,所谓元数据,就是" ...

  9. 学券制(教育券、school voucher)

    美国「学券制」是怎样的一种制度?它为什么是共和党的执政政策?它在美国及其它地区有实施吗?效果如何?能否在保证公平的同时,通过市场提高教育质量? 作者:冉筱韬链接:https://www.zhihu.c ...

随机推荐

  1. java 字符串转为list

     List<String> idList = Arrays.asList(irIds.split(",")); 

  2. 201771010117马兴德 实验二 Java基本程序设计(1)

    实验二 Java基本程序设计(1)  第一部分    理论知识的学习. 第三章Java基本程序设计结构 1  基本知识: (1)标识符:标识符由字母.下划线.美元符号和数字组成,且第一个符号不能为数字 ...

  3. E. Alternating Tree 树点分治|树形DP

    题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1)  注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...

  4. es6的数组操作

    //foreach 迭代 var arr = [1, 2, 3]; var sum = 0; arr.forEach(function(value, index, array) { console.l ...

  5. DBCP连接池和事物

    工具类案例 public static final String DRIVER = "com.mysql.jdbc.Driver"; public static final Str ...

  6. ASP.NET Core Blazor Webassembly 之 组件

    关于组件 现在前端几大轮子全面组件化.组件让我们可以对常用的功能进行封装,以便复用.组件这东西对于搞.NET的同学其实并不陌生,以前ASP.NET WebForm的用户控件其实也是一种组件.它封装ht ...

  7. [Firefox附加组件]0001.入门

    Firefox 火狐浏览器,拥有最快.最安全的上网体验,并且火狐拥有超过一万个的 扩展(add-ons),提供各种不同的扩展功能,您可以简单的下载.安装这些扩展以增强您的火狐功能,帮助您更好.更个性化 ...

  8. 删除节点与插入节点 & innerHTML

    1.测试removeChild()方法: 删除节点dom9.html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" &q ...

  9. 跨域解决方案 - 跨域资源共享cors

    目录 1. cors 介绍 2. 原理 3. cors 解决跨域 4. 自定义HTTP 头部字段解决跨域 5. 代码演示 5. 参考链接 1. cors 介绍 cors 说的是一个机制,其实相当于一个 ...

  10. Java实现 LeetCode 752 打开转盘锁(暴力)

    752. 打开转盘锁 你有一个带有四个圆形拨轮的转盘锁.每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' .每个拨轮可以自由旋 ...