BZOJ2690 : 字符串游戏
离线算法:
先将所有涉及到的串建成字典树,然后用线段树维护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 : 字符串游戏的更多相关文章
- BZOJ2690: 字符串游戏(平衡树动态维护Dfs序)
Description 给定N个仅有a~z组成的字符串ai,每个字符串都有一个权值vi,有M次操作,操作分三种: Cv x v':把第x个字符串的权值修改为v' Cs x a':把第x个字符串修改成a ...
- BZOJ2121 字符串游戏
Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其 他一些字符串的集合S,然后他可以进行以下操作:对于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删 ...
- BZOJ2121: 字符串游戏(DP)(字符串删单词,求最多可以删去多少)
2121: 字符串游戏 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 672 Solved: 376[Submit][Status][Discuss ...
- 20181228 模拟赛 T3 字符串游戏 strGame 博弈论 字符串
3 字符串游戏(strGame.c/cpp/pas) 3.1 题目描述 pure 和 dirty 决定玩 T 局游戏.对于每一局游戏,有n个字符串,并且每一局游戏由K轮组成.具体规则如下:在每一轮 ...
- BZOJ 2121: 字符串游戏 区间DP + 思维
Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对 于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删 ...
- QuickHit项目(输出字符串游戏)
public class leve { private int leveNo; private int strLength; private int strTimes; private int tim ...
- 字符串游戏(strgame)——博弈
题目 [题目描述] pure 和 dirty 决定玩 $T$ 局游戏.对于每一局游戏,有 $n$ 个字符串,并且每一局游戏由 $K$ 轮组成.具体规则如下:在每一轮游戏中,最开始有一个空串,两者轮流向 ...
- noi.ac 字符串游戏
题面 Zhangzj和Owaski在玩一个游戏.最开始有一个空的01串,Zhangzj和Owaski轮流进行操作,Zhangzj先走.每次进行操作的人可以在串上任意位置加一个新的字符,由于串是01串, ...
- 【bzoj2121】字符串游戏 区间dp
题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...
随机推荐
- 第9章 使用ssh服务管理远程主机。
章节简述: 学习使用nmtui命令配置网卡参数.手工将多块网卡做绑定.使用nmcli命令查看网卡信息和使用ss命令查看网络及端口状态. 完整演示sshd服务配置方法并详细讲述每个参数的作用,实战基于密 ...
- magic-encoding
(文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) 今天页面跳转都出问题了,各种方法都试过了, log里说语法错误,问了pp,他说是汉字的原因...果 ...
- Python win7下 django-admin.py startproject mysite命令没有创建mysite?
解决方案 解决:这个命令在XP下正常(我没试过),我用的win7,无法创建.这属于django的一个bug. 方法是:修改注册表中 HKEY_CLASSES_ROOT/Applications/pyt ...
- 2014-08-07 SSDB 使用 rocksdb 引擎
http://www.ideawu.net/blog/archives/824.html 为了满足各位对 Facebook 出品的 rocksdb 的爱好, SSDB 数据库也可以使用 rocksdb ...
- Ninject学习笔记<二>
本文转载自kuangkro 如果给您带来不便请联系博主 一.控制反转和依赖注入 Ninject是一个轻量级的基于.Net平台的依赖注入(IOC)框架.所谓的IOC,即控制反转(Inversion of ...
- Maximum Gap
Given an unsorted array, find the maximum difference between the successive elements in its sorted f ...
- gpart 使用笔记
需求 将260G 的/home 分区拆成/home与/data,原/home分区上的数据不用保留,新/home为100G,剩余空间给/data gpart过程 1.df 结果: # Device ...
- 升级Windows10后Apache服务器启动失败的解决方法
升级windows10系统后,微软内置了ASP.NET的web高级服务,默认安装了IIS服务器和MSSQL数据库,因为80端口被占用的原因,导致Apache服务器无法正常启动,但是MySQL服务一切正 ...
- BestCoder18 1002.Math Problem(hdu 5105) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5105 题目意思:给出一个6个实数:a, b, c, d, l, r.通过在[l, r]中取数 x,使得 ...
- mybatis异常:Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}问题分析及解决
转载自:http://blog.csdn.net/jackpk/article/details/44158701 mybatis异常:Improper inline parameter map for ...