离线算法:

先将所有涉及到的串建成字典树,然后用线段树维护dfs序,时间复杂度$O(m\log L)$。

在线算法:

用替罪羊树动态维护Trie树的dfs序即可,时间复杂度$O(L\log L)$。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2100010,M=50010;const double A=0.77;
int Type,n,m,i,x,y,loc[M],w[M],trie[N>>1][26],st[N>>1],en[N>>1],ct,ans;
char op[5],s[N];
namespace Subtask1{
int cnt,dfn,v[N],tag[N],c,d,p;
struct P{int x,y;P(){}P(int _x,int _y){x=_x,y=_y;}}q[250010];
void dfs(int x){
st[x]=++dfn;
for(int i=0;i<26;i++)if(trie[x][i])dfs(trie[x][i]);
en[x]=dfn;
}
inline void tag1(int x,int p){v[x]+=p;tag[x]+=p;}
void change(int x,int a,int b){
if(c<=a&&b<=d){tag1(x,p);return;}
if(tag[x])tag1(x<<1,tag[x]),tag1(x<<1|1,tag[x]),tag[x]=0;
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid);
if(d>mid)change(x<<1|1,mid+1,b);
v[x]=max(v[x<<1],v[x<<1|1]);
}
inline void insert(int p){
gets(s);
int l=strlen(s);register int x=0,i=0;
for(int w;i<l;i++)if(s[i]>='a'){
if(!trie[x][w=s[i]-'a'])trie[x][w]=++ct;
x=trie[x][w];
}
loc[p]=x;
}
void work(){
for(i=1;i<=n;i++)insert(i);
for(i=1;i<=n;i++)scanf("%d",&w[i]),q[++cnt]=P(loc[i],max(w[i],0));
while(m--){
scanf("%s",op);
if(op[0]=='Q')q[++cnt]=P(-1,0);
if(op[1]=='v'){
scanf("%d%d",&x,&y);
q[++cnt]=P(loc[x],max(y,0)-max(w[x],0));
w[x]=y;
}
if(op[1]=='s'){
scanf("%d",&x);
if(w[x]>0)q[++cnt]=P(loc[x],-w[x]);
insert(x);
if(w[x]>0)q[++cnt]=P(loc[x],w[x]);
}
}
dfs(0);
for(i=1;i<=cnt;i++)if(q[i].x<0)printf("%d\n",v[1]);else c=st[q[i].x],d=en[q[i].x],p=q[i].y,change(1,1,dfn);
}
}
namespace Subtask2{
int size[N],son[N][2],val[N],h[N],tag[N],f[N],tot,root,data[N],id[N],cnt;
int P,B,C,D;
inline void umax(int&a,int b){if(a<b)a=b;}
inline int newnode(int x,int p,int fa){
f[x]=fa;size[x]=1;son[x][0]=son[x][1]=0;
h[x]=val[x]=p;tag[x]=0;
return x;
}
inline void tag1(int x,int p){h[x]+=p;val[x]+=p;tag[x]+=p;}
inline void pb(int x){
if(tag[x]){
if(son[x][0])tag1(son[x][0],tag[x]);
if(son[x][1])tag1(son[x][1],tag[x]);
tag[x]=0;
}
}
inline void up(int x){
h[x]=val[x];
if(son[x][0])umax(h[x],h[son[x][0]]);
if(son[x][1])umax(h[x],h[son[x][1]]);
}
int ins(int x){
size[x]++;pb(x);
if(!son[x][B])return son[x][B]=newnode(++tot,P,x);
return ins(son[x][B]);
}
void dfs(int x){
pb(x);
if(son[x][0])dfs(son[x][0]);
data[++cnt]=val[x];id[cnt]=x;
if(son[x][1])dfs(son[x][1]);
}
int build(int fa,int l,int r){
int mid=(l+r)>>1,x=newnode(id[mid],data[mid],fa);
if(l==r)return x;
if(l<mid)size[x]+=size[son[x][0]=build(x,l,mid-1)];
if(r>mid)size[x]+=size[son[x][1]=build(x,mid+1,r)];
return up(x),x;
}
inline int rebuild(int x){cnt=0;dfs(x);return build(f[x],1,cnt);}
inline int kth(int k){
register int x=root,rank,t;
while(1){
size[x]++;pb(x);
rank=size[son[x][0]]+1;
if(k==rank)return x;
if(k<rank)x=son[x][0];else k-=rank,x=son[x][1];
}
}
inline int rank(register int x){
int ans=size[son[x][0]]+1;
while(f[x]){
if(son[f[x]][1]==x)ans+=size[son[f[x]][0]]+1;
x=f[x];
}
return ans;
}
inline void kthins(int k){
register int x=kth(k);
if(son[x][0])B=1,x=ins(son[x][0]);else{
son[x][0]=newnode(++tot,P,x);
x=son[x][0];
}
while((double)size[son[x][0]]<A*size[x]&&(double)size[son[x][1]]<A*size[x])x=f[x];
if(!x)return;
if(x==root){root=rebuild(x);return;}
int y=f[x],b=son[y][1]==x,now=rebuild(x);
son[y][b]=now;
}
inline void modify(int x,int a,int b){
if(!x)return;
if(C<=a&&b<=D){tag1(x,P);return;}
pb(x);
int mid=a+size[son[x][0]];
if(C<=mid&&mid<=D)val[x]+=P;
if(C<mid)modify(son[x][0],a,mid-1);
if(D>mid)modify(son[x][1],mid+1,b);
up(x);
}
inline int getval(int x){
cnt=0;
for(register int i=x;i;i=f[i])id[++cnt]=i;
while(cnt)pb(id[cnt--]);
return val[x];
}
inline void addleaf(int x,int y){
int k=rank(en[x]);P=getval(en[x]);
st[y]=tot+2,en[y]=tot+1;
kthins(k);
kthins(k);
}
inline void subtreeadd(int x,int y){C=rank(st[x]),D=rank(en[x]),P=y;modify(root,1,tot);}
inline void insert(int p){
gets(s);
int l=strlen(s);register int x=0,i=0;
for(int w;i<l;i++)if(s[i]>='a'){
w=(s[i]-'a'+ans)%26;
if(!trie[x][w])addleaf(x,trie[x][w]=++ct);
x=trie[x][w];
}
loc[p]=x;
}
void work(){
root=build(0,st[0]=id[1]=1,tot=en[0]=id[2]=2);
for(i=1;i<=n;i++)insert(i);
for(i=1;i<=n;i++)scanf("%d",&w[i]),subtreeadd(loc[i],max(w[i],0));
while(m--){
scanf("%s",op);
if(op[0]=='Q')printf("%d\n",ans=h[root]);
if(op[1]=='v'){
scanf("%d%d",&x,&y);
y=min(1000,y+ans%1000);
subtreeadd(loc[x],max(y,0)-max(w[x],0));
w[x]=y;
}
if(op[1]=='s'){
scanf("%d",&x);
if(w[x]>0)subtreeadd(loc[x],-w[x]);
insert(x);
if(w[x]>0)subtreeadd(loc[x],w[x]);
}
}
}
}
int main(){
scanf("%d%d%d",&Type,&n,&m);gets(s);
if(Type==1)Subtask1::work();else Subtask2::work();
return 0;
}

  

BZOJ2690 : 字符串游戏的更多相关文章

  1. BZOJ2690: 字符串游戏(平衡树动态维护Dfs序)

    Description 给定N个仅有a~z组成的字符串ai,每个字符串都有一个权值vi,有M次操作,操作分三种: Cv x v':把第x个字符串的权值修改为v' Cs x a':把第x个字符串修改成a ...

  2. BZOJ2121 字符串游戏

    Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其 他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删 ...

  3. BZOJ2121: 字符串游戏(DP)(字符串删单词,求最多可以删去多少)

    2121: 字符串游戏 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 672  Solved: 376[Submit][Status][Discuss ...

  4. 20181228 模拟赛 T3 字符串游戏 strGame 博弈论 字符串

    3  字符串游戏(strGame.c/cpp/pas) 3.1  题目描述 pure 和 dirty 决定玩 T 局游戏.对于每一局游戏,有n个字符串,并且每一局游戏由K轮组成.具体规则如下:在每一轮 ...

  5. BZOJ 2121: 字符串游戏 区间DP + 思维

    Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对 于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删 ...

  6. QuickHit项目(输出字符串游戏)

    public class leve { private int leveNo; private int strLength; private int strTimes; private int tim ...

  7. 字符串游戏(strgame)——博弈

    题目 [题目描述] pure 和 dirty 决定玩 $T$ 局游戏.对于每一局游戏,有 $n$ 个字符串,并且每一局游戏由 $K$ 轮组成.具体规则如下:在每一轮游戏中,最开始有一个空串,两者轮流向 ...

  8. noi.ac 字符串游戏

    题面 Zhangzj和Owaski在玩一个游戏.最开始有一个空的01串,Zhangzj和Owaski轮流进行操作,Zhangzj先走.每次进行操作的人可以在串上任意位置加一个新的字符,由于串是01串, ...

  9. 【bzoj2121】字符串游戏 区间dp

    题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...

随机推荐

  1. 暑假热身 D. 条形码设计

    校ACM队准备筹划向学校批请一个专用机房.但是为了防止它变成公用机房,FL建议采用刷卡进入的办法,她设计了一种条形码,每人都对应一个.这种大小为2*n的条形码由以下三种元素构成:1*2.2*1.2*2 ...

  2. typedef 各类定义,各类问题大全

    第一篇:typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定 ...

  3. Cannot locate factory for objects of type DefaultGradleConnector, as ConnectorServiceRegistry has been closed.

    现象:更换android studio libs文件夹下的jar包,重新编译代码报错:Cannot locate factory for objects of type DefaultGradleCo ...

  4. 在 FREEBUF 投放广告

    在 FREEBUF 投放广告 FreebuF黑客与极客—高质量的全球互联网安全媒体,同时也是爱好者们交流.分享安全技术的最佳平台.本站读者群以IT.政企信息安全人员.互联网安全爱好者和学生为主,对互联 ...

  5. 【Hibernate】Hibernate系列8之管理session

    管理session 更简单的,注入对象:

  6. 面向侧面的程序设计AOP-------《一》概述

    Aspect-Oriented Programming(面向方面编程,AOP)正好可以解决这一问题.它允许开发者动态地修改静态的OO模型,构造出一个能够不断增长以满足新增需求的系统,就象现实世界中的对 ...

  7. Subarray Sum & Maximum Size Subarray Sum Equals K

    Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code sho ...

  8. 39.递归颠倒栈[ReverseStack]

    [题目] 用递归颠倒一个栈.例如输入栈{1, 2, 3, 4, 5},1在栈顶.颠倒之后的栈为{5, 4, 3, 2, 1},5处在栈顶. [分析] 乍一看到这道题目,第一反应是把栈里的所有元素逐一p ...

  9. codeforces A. Sereja and Bottles 解题报告

    题目链接:http://codeforces.com/problemset/problem/315/A 题目意思:有n个soda bottles,随后给出这n个soda bottles的信息.已知第 ...

  10. SpringJDBC的简单应用

    此处写上应用JdbcTemplate的dao操作数据库的一些代码(含基本的增删改查,注:重点是查询出多条语句的写法): package org.sakaiproject.zhaorui.dao.imp ...