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

Description

给定N个仅有a~z组成的字符串ai,每个字符串都有一个权值vi,有M次操作,操作分三种:
Cv x v':把第x个字符串的权值修改为v'
Cs x a':把第x个字符串修改成a'
Q:求出当前的最大权字符串集合,使得这个集合中的字符串经过重新排列后满足除最后一个字符串外,前一个字符
串是后一个的前缀(两个字符串相同也是前缀关系,也可以一个字符串都不选)
前50%的数据可以接受离线算法,后50%的数据要求在线算法。

Input

输入的第一行包含一个正整数Test表示当前的数据类型。
输入的第二行包含两个正整数N,M表示字符串数和操作数。
以下N行,每行一个字符串ai
第N+3行包含N个整数vi
以下M行,为M次操作,操作有三种Cv x v',Cs x a',Q,第三种操作如题目描述一样,对于Test=1的修改操作,不用
做 任何变化,对于Test=2的修改操作,假设当前最后一次询问操作的答案是ans(如果还没有询问操作,ans=0),那
么对于第 一种操作中的v'=min(1000,v'+(ans mod 1000)),对于第二种操作的字符串a',它的每一位都要加上ans m
od 26(a~z循环)
数据分两种,A类数据可以用离线的方法来完成,B类数据必须使用在线算法。
令len=输入数据中所有出现的字符串总长度
数据分两种,A类数据可以用离线的方法来完成,B类数据必须使用在线算法。
N<=50000,M<=10^5,Len<=10^6
 
 

Output

对于每一次询问输出合法的最大权字符串集合的权值和

Sample Input

1
5 5
aba
ab
babb
abaa
abab
-2 1 4 2 3
Q
Cv 1 2
Q
Cs 3 abaab
Q

Sample Output

4
6
9

解题思路:

相当于插寻trie树上到根节点最大权路径。
修改单点对子树产生贡献。
每次插入/删除一条链。
Dfs序动态维护就好了。
代码1(卡常压缩版100行):
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 typedef long long lnt;
  6 struct trnt{int L,R,fa,rnd,wgt,val,ind,len,mxv,lzt_l,lzt_v;}T[2000010];
  7 struct trie{int ch[26],val;}t[1500010];
  8 int Rt,Rtl,Rtm,Rtr,siz,n,m,Tn,H;
  9 char cmd[100],str[2000010];
 10 int pos[1300010],val[1300010];
 11 inline int Rd(void){
 12     int ans=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 13     while(ch<='9'&&ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans*f;
 14 }
 15 inline void Up(int W){
 16     const int Z=T[W].L,C=T[W].R;
 17     T[W].wgt=1,T[W].mxv=T[W].val;
 18     if(Z)T[W].mxv=std::max(T[W].mxv,T[Z].mxv),
 19     T[W].wgt+=T[Z].wgt;T[Z].fa=W;
 20     if(C)T[W].mxv=std::max(T[W].mxv,T[C].mxv),
 21     T[W].wgt+=T[C].wgt;T[C].fa=W;
 22     return ;
 23 }
 24 inline void A(int W,int v)
 25 {if(!W)return ;T[W].val+=v,T[W].mxv+=v,T[W].lzt_v+=v;return ;}
 26 inline void Al(int W,int l){if(!W)return ;T[W].ind+=l;T[W].lzt_l+=l;return ;}
 27 inline void Dn(int W){
 28     int &Z=T[W].L,&C=T[W].R;
 29     if(T[W].lzt_v){A(Z,T[W].lzt_v);A(C,T[W].lzt_v);T[W].lzt_v=0;}
 30     if(T[W].lzt_l){Al(Z,T[W].lzt_l);Al(C,T[W].lzt_l);T[W].lzt_l=0;}
 31     return ;
 32 }
 33 inline void Rl(int W){if(T[W].fa)Rl(T[W].fa);Dn(W);return ;}
 34 inline void St(int W,int k,int &ll,int &rr){    
 35     int &Z=T[W].L,&C=T[W].R;
 36     if(!W)ll=rr=0;
 37     else{Dn(W);if(T[Z].wgt>=k){rr=W;St(Z,k,ll,Z);}else{ll=W;St(C,k-T[Z].wgt-1,C,rr);}Up(W);}
 38     return ;
 39 }
 40 inline int Mg(int ll,int rr){
 41     if(!ll||!rr)return ll|rr;
 42     if(T[ll].rnd<T[rr].rnd)
 43     {Dn(ll);T[ll].R=Mg(T[ll].R,rr);Up(ll);return ll;}
 44     else{Dn(rr);T[rr].L=Mg(ll,T[rr].L);Up(rr);return rr;}
 45     return 0;
 46 }
 47 inline int Rk(int W){
 48     Rl(W);
 49     int Z=T[W].L,ans=T[Z].wgt+1;
 50     while(W){if(T[T[W].fa].R==W)ans+=T[T[T[W].fa].L].wgt+1;W=T[W].fa;}
 51     return ans;
 52 }
 53 inline void Bc(char *a,int from,int len,int &rt,int v){
 54     int dlt=len-from+1;Rl(rt);
 55     St(Rt,T[rt].ind-1,Rtl,Rtr);
 56     St(Rtr,T[rt].len,Rtm,Rtr);
 57     int dfn=T[rt].ind+T[rt].len-1;
 58     for(int i=from;i<=len;i++){
 59         dfn++;int c=a[i]-'a';t[rt].ch[c]=++siz;T[siz].rnd=rand();
 60         T[siz].val=v;T[siz].wgt=1;T[siz].ind=dfn;T[siz].len=len-i+1;
 61         Rtm=Mg(Rtm,siz);rt=t[rt].ch[c];
 62     }
 63     int ROOT=1;for(int i=1;i<=from;i++){int c=a[i]-'a';T[ROOT].len+=dlt;ROOT=t[ROOT].ch[c];}
 64     Rt=Mg(Mg(Rtl,Rtm),Rtr);St(Rt,Rk(siz),Rtl,Rtr);
 65     if(Rtr)Al(Rtr,dlt);Rt=Mg(Rtl,Rtr);return ;
 66 }
 67 inline void Is(char *a,int &rt){
 68     rt=1;int len=strlen(a+1),v=0;
 69     for(int i=1;i<=len;i++){
 70         int c=a[i]-'a';v+=t[rt].val;
 71         if(!t[rt].ch[c])return Bc(a,i,len,rt,v);rt=t[rt].ch[c];
 72     }return ;
 73 }
 74 inline void Cd(int i,int f){
 75     t[pos[i]].val+=f*val[i];Rl(pos[i]);St(Rt,T[pos[i]].ind-1,Rtl,Rtr);
 76     St(Rtr,T[pos[i]].len,Rtm,Rtr);A(Rtm,val[i]*f);
 77     Rt=Mg(Mg(Rtl,Rtm),Rtr);return ;
 78 }
 79 int main()
 80 {
 81     Tn=Rd();n=Rd();m=Rd();Rt=++siz;T[Rt].rnd=rand();
 82     T[Rt].len=T[Rt].ind=1;
 83     for(int i=1;i<=n;i++)scanf("%s",str+1),Is(str,pos[i]);
 84     for(int i=1;i<=n;i++){val[i]=Rd();if(val[i]<=0)val[i]=0;else Cd(i,1);}
 85     while(m --> 0){
 86         scanf("%s",cmd+1);
 87         if(cmd[1]=='Q')printf("%d\n",H=T[Rt].mxv);
 88         if(cmd[2]=='v'){
 89             int x=Rd(),v=Rd();if(Tn==2)v=std::min(1000,v+H%1000);
 90             Cd(x,-1);if(v<=0)v=0;val[x]=v;Cd(x,1);
 91         }
 92         if(cmd[2]=='s'){
 93             int x=Rd();scanf("%s",str+1);
 94             if(Tn==2){int len=strlen(str+1);
 95             for(int i=1;i<=len;i++)str[i]=((int)(str[i]-'a')+H)%26+'a';}
 96             Cd(x,-1);Is(str,pos[x]);Cd(x,1);
 97         }
 98     }
 99     return 0;
100 }
极限版

代码2:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #define lll tr[spc].ls
  6 #define rrr tr[spc].rs
  7 typedef long long lnt;
  8 inline int read(void)
  9 {
 10     int ans=0,f=1;
 11     char ch=getchar();
 12     while(ch<'0'||ch>'9')
 13     {
 14         if(ch=='-')f=-1;
 15         ch=getchar();
 16     }
 17     while(ch>='0'&&ch<='9')
 18     {
 19         ans=ans*10+ch-'0';
 20         ch=getchar();
 21     }
 22     return ans*f;
 23 }
 24 struct trnt{
 25     int ls;
 26     int rs;
 27     int fa;
 28     int rnd;
 29     int wgt;
 30     int val;
 31     int ind;
 32     int len;
 33     int mxv;
 34     int lzt_l;
 35     int lzt_v;
 36 }tr[1000010];
 37 struct trie{
 38     int ch[26];
 39     int val;
 40 }t[1000010];
 41 int root;
 42 int rootl;
 43 int rootm;
 44 int rootr;
 45 int siz;
 46 int n,m;
 47 int testno;
 48 int lastans;
 49 char cmd[100];
 50 int pos[100010];
 51 int val[100010];
 52 char str[1000010];
 53 inline void pushup(int spc)
 54 {
 55     tr[spc].wgt=1;
 56     tr[spc].mxv=tr[spc].val;
 57     if(lll)
 58     {
 59         tr[spc].mxv=std::max(tr[spc].mxv,tr[lll].mxv);
 60         tr[spc].wgt+=tr[lll].wgt;
 61         tr[lll].fa=spc;
 62     }
 63     if(rrr)
 64     {
 65         tr[spc].mxv=std::max(tr[spc].mxv,tr[rrr].mxv);
 66         tr[spc].wgt+=tr[rrr].wgt;
 67         tr[rrr].fa=spc;
 68     }
 69     return ;
 70 }
 71 inline void ADD(int spc,int v)
 72 {
 73     if(!spc)return ;
 74     tr[spc].val+=v;
 75     tr[spc].mxv+=v;
 76     tr[spc].lzt_v+=v;
 77     return ;
 78 }
 79 inline void ADDLEN(int spc,int l)
 80 {
 81     if(!spc)return ;
 82     tr[spc].ind+=l;
 83     tr[spc].lzt_l+=l;
 84     return ;
 85 }
 86 inline void pushdown(int spc)
 87 {
 88     if(tr[spc].lzt_v)
 89     {
 90         ADD(lll,tr[spc].lzt_v);
 91         ADD(rrr,tr[spc].lzt_v);
 92         tr[spc].lzt_v=0;
 93     }
 94     if(tr[spc].lzt_l)
 95     {
 96         ADDLEN(lll,tr[spc].lzt_l);
 97         ADDLEN(rrr,tr[spc].lzt_l);
 98         tr[spc].lzt_l=0;
 99     }
100     return ;
101 }
102 void recal(int spc)
103 {
104     if(tr[spc].fa)recal(tr[spc].fa);
105     pushdown(spc);
106     return ;
107 }
108 void split(int spc,int k,int &ll,int &rr)
109 {
110     if(!spc)ll=rr=0;
111     else{
112         pushdown(spc);
113         if(tr[lll].wgt>=k)
114         {
115             rr=spc;
116             split(lll,k,ll,lll);
117         }else{
118             ll=spc;
119             split(rrr,k-tr[lll].wgt-1,rrr,rr);
120         }
121         pushup(spc);
122     }
123     return ;
124 }
125 int merge(int ll,int rr)
126 {
127     if(!ll||!rr)return ll|rr;
128     if(tr[ll].rnd<tr[rr].rnd)
129     {
130         pushdown(ll);
131         tr[ll].rs=merge(tr[ll].rs,rr);
132         pushup(ll);
133         return ll;
134     }else{
135         pushdown(rr);
136         tr[rr].ls=merge(ll,tr[rr].ls);
137         pushup(rr);
138         return rr;
139     }
140     return 0;
141 }
142 int rank(int spc)
143 {
144     recal(spc);
145     int ans=tr[lll].wgt+1;
146     while(spc)
147     {
148         if(tr[tr[spc].fa].rs==spc)ans+=tr[tr[tr[spc].fa].ls].wgt+1;
149         spc=tr[spc].fa;
150     }
151     return ans;
152 }
153 void build_chain(char *a,int from,int len,int &rt,int v)
154 {
155     int dlt=len-from+1;
156     int ROOT=1;
157     recal(rt);
158     split(root,tr[rt].ind-1,rootl,rootr);
159     split(rootr,tr[rt].len,rootm,rootr);
160     int dfn=tr[rt].ind+tr[rt].len-1;
161     for(int i=from;i<=len;i++)
162     {
163         dfn++;
164         int c=a[i]-'a';
165         t[rt].ch[c]=++siz;
166         tr[siz].rnd=rand();
167         tr[siz].val=v;
168         tr[siz].wgt=1;
169         tr[siz].ind=dfn;
170         tr[siz].len=len-i+1;
171         rootm=merge(rootm,siz);
172         rt=t[rt].ch[c];
173     }
174     for(int i=1;i<=from;i++)
175     {
176         int c=a[i]-'a';
177         tr[ROOT].len+=dlt;
178         ROOT=t[ROOT].ch[c];
179     }
180     root=merge(merge(rootl,rootm),rootr);
181     split(root,rank(siz),rootl,rootr);
182     if(rootr)ADDLEN(rootr,dlt);
183     root=merge(rootl,rootr);
184     return ;
185 }
186 void insert(char *a,int &rt)
187 {
188     int len=strlen(a+1);
189     rt=1;
190     int v=0;
191     for(int i=1;i<=len;i++)
192     {
193         int c=a[i]-'a';
194         v+=t[rt].val;
195         if(!t[rt].ch[c])return build_chain(a,i,len,rt,v);
196         rt=t[rt].ch[c];
197     }
198     return ;
199 }
200 void change_dfn(int i,int f)
201 {
202     t[pos[i]].val+=f*val[i];
203     recal(pos[i]);
204     split(root,tr[pos[i]].ind-1,rootl,rootr);
205     split(rootr,tr[pos[i]].len,rootm,rootr);
206     ADD(rootm,val[i]*f);
207     root=merge(merge(rootl,rootm),rootr);
208     return ;
209 }
210 int main()
211 {
212     srand(17);
213     testno=read();
214     n=read();m=read();
215     root=++siz;
216     tr[root].rnd=rand();
217     tr[root].len=tr[root].ind=1;
218     for(int i=1;i<=n;i++)
219     {
220         scanf("%s",str+1);
221         insert(str,pos[i]);
222     }
223     for(int i=1;i<=n;i++)
224     {
225         val[i]=read();
226         if(val[i]<=0)val[i]=0;
227         else change_dfn(i,1);
228     }
229     while(m --> 0)
230     {
231         scanf("%s",cmd+1);
232         if(cmd[1]=='Q')
233             printf("%d\n",lastans=tr[root].mxv);
234         if(cmd[2]=='v')
235         {
236             int x=read(),v=read();
237             if(testno==2)v=std::min(1000,v+lastans%1000);
238             change_dfn(x,-1);
239             if(v<=0)v=0;
240             val[x]=v;
241             change_dfn(x,1);
242         }
243         if(cmd[2]=='s')
244         {
245             int x=read();
246             scanf("%s",str+1);
247             if(testno==2)
248             {
249                 int len=strlen(str+1);
250                 for(int i=1;i<=len;i++)
251                     str[i]=((int)(str[i]-'a')+lastans)%26+'a';
252             }
253             change_dfn(x,-1);
254             insert(str,pos[x]);
255             change_dfn(x,1);
256         }
257     }
258     return 0;
259 }

转载于:https://www.cnblogs.com/blog-Dr-J/p/10462938.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【第一趴】初探uni-app(uni-app发行者、uni-app推出背景、为什么选择uni-app)

文章目录写在前面DCloud当下跨平台开发存在的问题为什么选择uni-app写在最后写在前面 聚沙成塔——每天进步一点点&#xff0c;大家好我是几何心凉&#xff0c;不难发现越来越多的前端招聘JD中都加入了uni-app 这一项&#xff0c;它也已经成为前端开发者不可或缺的一项技能了&…

Rocket - tilelink - Atomics

https://mp.weixin.qq.com/s/TSwKL_qm-b-0e8x7r--hhg 简单介绍Atomics中数学运算、逻辑运算的实现。​​1. ioAtomics是一个硬件模块&#xff0c;他继承自Modules&#xff1a;​​IO端口定义如下&#xff1a;​​其中&#xff1a;a. write: 是否写操作&#xff1b;b. a&#xf…

“勤学会”火爆来袭

文章目录勤学会是什么&#xff1f;勤学会存在的意义是什么强大的助学团勤学会如何帮助大家学习参与勤学会能得什么奖品专属C计划加入勤学会勤学会是什么&#xff1f; 他来了他来了&#xff0c;其实两个月前勤学会的概念产品就已经出现了&#xff0c;只不过因为了 1024 大型活动…

LeetCode -- 204. Count Primes

题目标签 HashTab&#xff08;哈希表&#xff09; 题意及思路 题意&#xff1a;略 思路&#xff1a;有关素数的题目我所知道有两种做法。一种是最基本的isPrime算法&#xff0c;关键点在循环判断时&#xff0c;上限为Math.sqrt(n) &#xff08;求n是否为素数&#xff09;。另外…

如何寻找无序数组中的第K大元素?

如何寻找无序数组中的第K大元素&#xff1f; 有这样一个算法题&#xff1a;有一个无序数组&#xff0c;要求找出数组中的第K大元素。比如给定的无序数组如下所示&#xff1a; 如果k6&#xff0c;也就是要寻找第6大的元素&#xff0c;很显然&#xff0c;数组中第一大元素是24&am…

测试MongoDB的自动分片

MongoDB的自动分片&#xff1a; test库分片配置&#xff1a; db.shards.find(){ "_id" : "shard0000", "host" : "127.0.0.1:29017", "state" : 1 }{ "_id" : "shard0001", "host" : "1…

线上CPU飚高(死循环,死锁……)?帮你迅速定位代码位置

top基本使用&#xff1a; top命令参考本篇文章 查看内存和CPU的top命令&#xff0c;别看输出一大堆&#xff0c;理解了其实很简单 top 命令运行图&#xff1a; 第一行&#xff1a;基本信息 第二行&#xff1a;任务信息 第三行&#xff1a;CPU使用情况 第四行&#xff1a;物理内…

zookeeper watch笔记

ZK其核心原理满足CP, 实现的是最终一致性, 它只保证顺序一致性. zookeeper 基于 zxid 以及阻塞队列的方式来实现请求的顺序一致性。如果一个client连接到一个最新的 follower 上&#xff0c;那么它 read 读取到了最新的数据&#xff0c;然后 client 由于网络原因重新连接到 zoo…

单机简单搭建一个kafka集群(没有进行内核参数和JVM的调优)

1.JDK安装 在我的部署单节点kafka的博客里有相关的方法。&#xff08;https://www.cnblogs.com/ToBeExpert/p/9789486.html &#xff09;zookeeper和kafka的压缩包下载地址也在单节点部署的这篇博客里。 1.zookeeper集群的搭建 将zookeeper.tar.gz解压为三个目录&#xff0c;例…

[翻译]三张卡片帮你记住TDD的基本原则

原文地址&#xff1a;http://blog.briandicroce.com/2008/03/14/three-index-cards-to-easily-remember-the-essence-of-test-driven-development/ 当我浏览ObjectMentor的博客的时候&#xff0c;其中一篇Tim Ottinger的“TDD on Three Index Cards”引起了我的注意。他回忆了他…

凉哥核心圈程序员必备十大图书推荐(一)

写在前面 凉哥核心圈程序员必备十大图书推荐&#xff08;一&#xff09;&#xff0c;各位伙伴应该一目了然了哈&#xff0c;没错凉哥准备出一系列图书推荐的文章&#xff0c;其实很多朋友在私下问凉哥除了大学的课程外自己要不要读一些技术类的书籍呢&#xff0c;答案当时要的…

了解大数据的特点、来源与数据呈现方式

本次作业来源于&#xff1a;https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2639 1.浏览2019春节各种大数据分析报告&#xff0c;例如&#xff1a; 这世间&#xff0c;再无第二个国家有能力承载如此庞大的人流量。http://www.sohu.com/a/290025769_313993春节人口迁…

强大而优雅,API 研发管理 EOLINKER 新版正式发布!

EOLINKER 于2019年3月3日正式发布新版本&#xff01;该版本大幅强化各个产品的功能、着重优化了全站的用户交互体验&#xff0c;并且EOLINKER AMS 产品正式更名为 EOLINKER API Studio ——API 工作室&#xff0c;旨在为您提供API文档管理、自动化测试以及开发协作等全方位服务…

MATLAB 与 Excel 接口

MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式&#xff1a;一种是通过 MATLAB 提供的 Excel 生成器&#xff0c;生成220 MATLAB 实用教程DLL 组件和 VBA 代码&#xff0c;实现 Excel 对 MATLAB 的调用&#xff1b;另一种是利用 MATLAB 提供的 Excellink 插件&#xff0c…

计算 1+2!+3!+4!+...20!=?

package algs.factorial;import java.math.BigInteger;/*** Author: areful* Date: 2019/3/6* 计算 sum(n!), n1,2, ... 20*/ public class NFactorial {public static void main(String[] args) {System.out.println(calcFactorial0(3));System.out.println(calcFactorial1(3)…

区块链基础语言(三)——Go语言开发工具

一、在Windows系统安装Goland 1.1 下载 官网地址&#xff1a;https://www.jetbrains.com/go/download/#sectionwindows 1.2 安装 a. 双击“goland-2018.1.5.exe”&#xff0c;单击“运行”&#xff0c;如图1所示&#xff1b; <图1> b. 如图2所示&#xff0c;单击“next”…

准备重新开始写了

工作很忙,而且前一段时间项目组由于方向和人员调整一直很动荡,所以就没有心情和时间来整理技术.准备重新开张了,好好写,争取每个月出一到两篇说得过去的文章.转载于:https://www.cnblogs.com/sun/archive/2008/06/12/1218220.html

Georgia and Bob POJ - 1704 阶梯Nim

$ \color{#0066ff}{ 题目描述 }$ Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, number the grids from left to right by 1, 2, 3, ..., and place N chessmen on different grids, as shown in the following figure for exampl…

Tomcat总结

Tomcat调优原理&#xff1a; 1、增加最大连接数&#xff08;增大值避免队列请求过多&#xff0c;导致响应缓慢&#xff09; 2、调整工作模式 Bio(BlockingI/O)&#xff1a;默认工作模式&#xff0c;阻塞式I/O操作&#xff0c;没有任何优化技术处理&#xff0c;性能比较低。Nio(…

JVM的监控工具之jstack

参考博客&#xff1a;https://www.jianshu.com/p/213710fb9e40 jstack&#xff08;Stack Trace for Java&#xff09;命令用于生成虚拟机当前时刻的线程快照&#xff08;一般称为threaddump或者javacore文件&#xff09;。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈…