题意:

Description

n列火车,每条有l节车厢。每节车厢有一种颜色(用小写字母表示)。有m次车厢交换操作。求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少。

Input

n l m (2 ≤ n ≤ 1000, 1 ≤ l ≤ 100, 0 ≤ m ≤ 100000) n行字符串,长度为l

m行,每行4个数a b c d,a车的第b个字符与c车第d个字符交换。

Output

n个数,在交换车厢的某个时刻,与该车颜色完全相同的火车最多数目。

题解:

由于$l$很小,可以直接哈希判断两列火车是否相同;

用splay来维护所有火车的哈希值,每次交换操作直接删除两个串的哈希值,交换字符重新计算哈希值后再插入即可;

每次下传标记的时候把哈希值相同的一段打上标记更新答案;

注意当交换的两个字符在同一个串中时要特殊处理,防止被删两次;

时间复杂度$O((l+logn)m)$

然而说起来很简单但我每次写平衡树都要调至少1h /微笑

代码:

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #include<cmath>
  6. #include<queue>
  7. #define inf 2147483647
  8. #define eps 1e-9
  9. #define H 173
  10. using namespace std;
  11. typedef unsigned long long ll;
  12. typedef double db;
  13. struct node{
  14. int son[],fa,siz;
  15. }t[];
  16. int n,l,m,x,y,a,b,rt,cnt=,ans[],tag[];
  17. ll pw[],hs[];
  18. char s[][];
  19. bool Son(int u){
  20. return t[t[u].fa].son[]==u;
  21. }
  22. void pushup(int u){
  23. t[u].siz=t[t[u].son[]].siz+t[t[u].son[]].siz+;
  24. }
  25. void pd(int u){
  26. if(tag[u]){
  27. ans[t[u].son[]]=max(ans[t[u].son[]],tag[u]);
  28. tag[t[u].son[]]=max(tag[t[u].son[]],tag[u]);
  29. ans[t[u].son[]]=max(ans[t[u].son[]],tag[u]);
  30. tag[t[u].son[]]=max(tag[t[u].son[]],tag[u]);
  31. tag[u]=;
  32. }
  33. }
  34. void rotate(int u){
  35. int f=t[u].fa,ff=t[f].fa,ch=Son(u),cf=Son(f);
  36. pd(f);
  37. pd(u);
  38. t[f].son[ch]=t[u].son[ch^];
  39. t[t[f].son[ch]].fa=f;
  40. t[ff].son[cf]=u;
  41. t[u].son[ch^]=f;
  42. t[u].fa=ff;
  43. t[f].fa=u;
  44. pushup(f);
  45. pushup(u);
  46. }
  47. void splay(int u,int to){
  48. for(;t[u].fa!=to;rotate(u)){
  49. int f=t[u].fa;
  50. if(t[f].fa!=to)rotate(Son(u)^Son(f)?u:f);
  51. }
  52. if(!to)rt=u;
  53. }
  54. int getpre(ll x){
  55. int nw=rt,u=rt;
  56. for(;nw;){
  57. if(x>hs[nw]){
  58. u=nw;
  59. nw=t[nw].son[];
  60. }else nw=t[nw].son[];
  61. }
  62. return u;
  63. }
  64. int getnxt(ll x){
  65. int nw=rt,u;
  66. for(;nw;){
  67. if(x<hs[nw]){
  68. u=nw;
  69. nw=t[nw].son[];
  70. }else nw=t[nw].son[];
  71. }
  72. return u;
  73. }
  74. int nxt(int u){
  75. int nw=t[u].son[];
  76. while(t[nw].son[])nw=t[nw].son[];
  77. return nw;
  78. }
  79. void ins(int x){
  80. int u=getpre(hs[x]),v=getnxt(hs[x]);
  81. splay(u,);
  82. splay(v,u);
  83. t[x].son[]=t[v].son[];
  84. t[t[x].son[]].fa=x;
  85. t[v].son[]=x;
  86. t[x].fa=v;
  87. pushup(x);
  88. pushup(v);
  89. pushup(u);
  90. ans[x]=max(ans[x],t[x].siz);
  91. tag[x]=max(tag[x],t[x].siz);
  92. }
  93. void del(int x){
  94. splay(x,);
  95. int u=nxt(x);
  96. splay(u,x);
  97. rt=u;
  98. t[u].son[]=t[x].son[];
  99. t[t[u].son[]].fa=u;
  100. t[u].fa=;
  101. pushup(u);
  102. t[x].son[]=t[x].son[]=;
  103. t[x].siz=;
  104. }
  105. void dfs(int u){
  106. pd(u);
  107. if(t[u].son[])dfs(t[u].son[]);
  108. if(t[u].son[])dfs(t[u].son[]);
  109. }
  110. int main(){
  111. scanf("%d%d%d",&n,&l,&m);
  112. pw[]=;
  113. for(int i=;i<=l;i++)pw[i]=pw[i-]*H;
  114. rt=n+;
  115. t[rt].siz=;
  116. hs[rt]=;
  117. t[rt].son[]=n+;
  118. t[n+].siz=;
  119. t[n+].fa=rt;
  120. hs[n+]=(1ll<<)-;
  121. for(int i=;i<=n;i++){
  122. scanf("%s",s[i]+);
  123. for(int j=;j<=l;j++){
  124. hs[i]=hs[i]*H+s[i][j];
  125. }
  126. ins(i);
  127. }
  128. for(int i=;i<=m;i++){
  129. scanf("%d%d%d%d",&x,&a,&y,&b);
  130. if(x==y){
  131. del(x);
  132. swap(s[x][a],s[x][b]);
  133. hs[x]=;
  134. for(int j=;j<=l;j++){
  135. hs[x]=hs[x]*H+s[x][j];
  136. }
  137. ins(x);
  138. }else{
  139. del(x);
  140. del(y);
  141. swap(s[x][a],s[y][b]);
  142. hs[x]=hs[y]=;
  143. for(int j=;j<=l;j++){
  144. hs[x]=hs[x]*H+s[x][j];
  145. hs[y]=hs[y]*H+s[y][j];
  146. }
  147. ins(x);
  148. ins(y);
  149. }
  150. }
  151. dfs(rt);
  152. for(int i=;i<=n;i++){
  153. printf("%d\n",ans[i]);
  154. }
  155. return ;
  156. }

【BZOJ1125】【POI2008】poc - splay+哈希的更多相关文章

  1. bzoj1125:[POI2008]Poc

    传送门 这个题好难卡啊. 看到这种题自然会想到字符串hash是不是,但是对于每次操作造成的影响需要\(O(n)\)的时间去更新,自然是不优的 可以发现这个更新可以用数据结构来维护,对于每个hash值开 ...

  2. 【BZOJ1125】[POI2008]Poc hash+map+SBT

    [BZOJ1125][POI2008]Poc Description n列火车,每条有l节车厢.每节车厢有一种颜色(用小写字母表示).有m次车厢交换操作.求:对于每列火车,在交换车厢的某个时刻,与其颜 ...

  3. BZOJ1014 JSOI2008火星人(splay+哈希)

    splay维护哈希值即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstd ...

  4. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

  5. [POI2008] Poc (原名 Trians) Treap+Hash

    这个题和千山鸟飞绝体现出了一种用平衡树解决动态集合问题,主要套路就是蜜汁标记. 这个题我一开始用替罪羊树搞了一下对了28个点,后来我换成了Treap一搞对了14个点,再后来发现被卡了Hash我竟然在自 ...

  6. BZOJ1014火星人prefix Splay維護序列 + 字符串哈希

    @[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. [POI2008]KLO && POC

    题意:给定一个序列 s1, s2,...sn,以及一个k,求一个连续的k个数,把s[i]...s[i+k-1]变成一个数s',使得sigma(|s[j]-s'|)(i<=j<=i+k-1) ...

  9. 【BZOJ1014】火星人(Splay,哈希)

    [BZOJ1014]火星人(Splay,哈希) 题面 BZOJ 题解 要动态维护这个串,一脸的平衡树. 那么用\(Splay\)维护这个哈希值就好了. 每次计算答案的时候二分+Splay计算区间哈希值 ...

随机推荐

  1. Ngnix--知识点

    ngnix擅长负载 均衡的反向代理 haproxy擅长高可用的反向代理,这个还支持TCP协议 ngnix只能支持HTTP和Email(这个HTTPS需要核实一下) ngnix和haproxy都需要ke ...

  2. 【android】uses-permission和permission具体解释

    1.<uses-permission>: 官方描写叙述: If an application needs access to a feature protected by a permis ...

  3. Effective C++ Item 28 避免返回对象内部数据的引用或指针

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie Item 31 经验:避免返回handles(包含 references.指针.迭代器)指向 ...

  4. android制作闪动的红心

    先上一张效果图吧: 说说这个东西的来源吧.今天突然想到笛卡尔心形图,想去看看能不能画个心出来,可是看到一篇不错的文章,那篇文章罗列了非常多关于心形的函数方程,这可把我高兴坏了,于是我选取了一个比較好看 ...

  5. 【cl】测试用例【文本框-电子邮箱】

    电子邮箱控件用例: 1.只输入字母,如:abc 2.只输入数字,如:123 3.空白.空格或回车等 4.特殊的字符,如:¥,$等 5.上述四种的组合 6.不正确的邮箱组合: ①.abc@sohucom ...

  6. 驱动开发(8)处理设备I/O控制函数DeviceIoControl

    本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan全部,转载请注明出处:http://blog.csdn.net/zuishikonghuan/article/d ...

  7. 二维数组+字符串split+Double包装类 例题

    将String s = "1,2;3,4,5;6,7,8" 存放在double类型的二维数组中,使得 d[0][0]=1.0 d[0][1]=2.0 d[1][0]=3.0 d[1 ...

  8. luogu3942 将军令 贪心

    题目大意:给你一个地图(树),共有1~n个驿站(点),编号分别为1~n,告诉你第ui个驿站与第vi个驿站有一条长度为1的路(边),每个小队(可以放在任意驿站上)最多有k的覆盖长度,问最多要放置多少个小 ...

  9. luogu2754 星际转移问题 网络流

    题目大意:地球与月球间有可容纳无限人的太空站,还有在太空站与星球间按周期行驶的.有固定容量的太空船,每一艘太空船从一个太空站驶往任一太空站耗时均为 1.地球上有一定数量的人,问所有人到月球最少需要多少 ...

  10. hdoj--1068--Girls and Boys(最大独立集)

    Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...