bzoj-1125 Poc
2015-09-14 11:17
274 查看
题意:
给出n个字符串,长度均为len;
有m次操作,每次将两个字符交换;
求每个字符串在任何时点上,与相同的它最多的字符串个数;
n<=1000,len<=100,m<=100000;
题解:
Poi!
字符串长度很小,我们先考虑到用Hash来判断字符串的相同;
这些部分很简单,但是统计任意时点对某个字符串的答案是很难的;
因为如果暴力更新的话复杂度是O(nm),所以不能这么搞;
而延迟更新也没有什么好办法,只能去找打标记的数据结构了;
这里我写了一个Splay,以Hash值大小为关键字排序;
修改时先将其转到根删掉,然后再修改之后插回去,
之后将Hash值相同的一段提出来打标记更新答案;
这样每次的复杂度是O(len+logn)的。。
注意将同一个字符串中的字符交换时,不要让它被删两次哦2333;
代码:
给出n个字符串,长度均为len;
有m次操作,每次将两个字符交换;
求每个字符串在任何时点上,与相同的它最多的字符串个数;
n<=1000,len<=100,m<=100000;
题解:
Poi!
字符串长度很小,我们先考虑到用Hash来判断字符串的相同;
这些部分很简单,但是统计任意时点对某个字符串的答案是很难的;
因为如果暴力更新的话复杂度是O(nm),所以不能这么搞;
而延迟更新也没有什么好办法,只能去找打标记的数据结构了;
这里我写了一个Splay,以Hash值大小为关键字排序;
修改时先将其转到根删掉,然后再修改之后插回去,
之后将Hash值相同的一段提出来打标记更新答案;
这样每次的复杂度是O(len+logn)的。。
注意将同一个字符串中的字符交换时,不要让它被删两次哦2333;
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #define N 1100 #define seed 1331 #define which(x) (ch[fa[x]][1]==x) using namespace std; typedef unsigned long long ll; int n,len; int size ,fa ,ch [2],cov ,ans ,root; char str [111]; ll val ,pow[111]; void Pushup(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void Pushdown(int x) { if(cov[x]) { ans[ch[x][0]]=max(ans[ch[x][0]],cov[x]); cov[ch[x][0]]=max(cov[ch[x][0]],cov[x]); ans[ch[x][1]]=max(ans[ch[x][1]],cov[x]); cov[ch[x][1]]=max(cov[ch[x][1]],cov[x]); cov[x]=0; } } void Rotate(int x) { int f=fa[x]; bool k=which(x); Pushdown(f),Pushdown(x); ch[f][k]=ch[x][!k]; ch[x][!k]=f; ch[fa[f]][which(f)]=x; fa[x]=fa[f]; fa[f]=x; fa[ch[f][k]]=f; Pushup(f); Pushup(x); } void Splay(int x,int g) { while(fa[x]!=g) { int f=fa[x]; if(fa[f]==g) { Rotate(x); break; } if(which(x)^which(f)) Rotate(x); else Rotate(f); Rotate(x); } if(!g) root=x; } int pre(ll v) { int p=root,ret=root; while(p) { if(v>val[p]) ret=p,p=ch[p][1]; else p=ch[p][0]; } return ret; } int sub(ll v) { int p=root,ret; while(p) { if(v<val[p]) ret=p,p=ch[p][0]; else p=ch[p][1]; } return ret; } void Down(int x) { if(!x) return ; Pushdown(x); Down(ch[x][0]); Down(ch[x][1]); } void Insert(int x) { int l=pre(val[x]),r=sub(val[x]); Splay(l,0),Splay(r,l); int t=ch[r][0]; fa[t]=x,ch[x][0]=t; fa[x]=r,ch[r][0]=x; Pushup(x),Pushup(r),Pushup(l); ans[x]=max(ans[x],size[x]); cov[x]=max(cov[x],size[x]); } void del(int x) { Splay(x,0); int p=ch[x][1]; while(ch[p][0]) p=ch[p][0]; Splay(p,x); ch[p][0]=ch[x][0]; fa[ch[p][0]]=p,fa[p]=0; root=p; Pushup(p); ch[x][0]=ch[x][1]=0; size[x]=1; } void init() { pow[0]=1; for(int i=1;i<=len;i++) pow[i]=pow[i-1]*seed; root=n+1,size[n+1]=2,ch[n+1][1]=n+2; size[n+2]=1,fa[n+2]=n+1; val[n+1]=0,val[n+2]=(1ll<<64)-1; } int main() { int m,i,j,k,a,b,x,y; scanf("%d%d%d",&n,&len,&m); init(); for(i=1;i<=n;i++) { scanf("%s",str[i]+1); for(j=1;j<=len;j++) val[i]=val[i]*seed+str[i][j]; Insert(i); } for(i=1;i<=m;i++) { scanf("%d%d%d%d",&x,&a,&y,&b); if(x==y) { del(x); swap(str[x][a],str[x][b]); for(j=1,val[x]=0;j<=len;j++) val[x]=val[x]*seed+str[x][j]; Insert(x); continue; } del(x),del(y); swap(str[x][a],str[y][b]); for(j=1,val[x]=val[y]=0;j<=len;j++) val[x]=val[x]*seed+str[x][j], val[y]=val[y]*seed+str[y][j]; Insert(x),Insert(y); } Down(root); for(i=1;i<=n;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- mysql mybaits批量更新时遇到的一个小问题
- WebLogic12安装过程详解
- JavaScript人脸识别技术及脸部识别JavaScript类库Tracking.js
- Git之Fork
- Developer--WebView
- 根据日历 计算某一天距离今天多少天,多少小时,多少分钟
- 如何自定义FloatingActionButton的大小
- Android 与服务器的通信方式
- 【原创】Django-ORM进阶
- leetcode面试准备:Add and Search Word - Data structure design
- 如何完全退出android应用程序
- 查询oracle用户IP
- 双系统(win7+ubuntu)中重装Ubuntu覆盖先前Ubuntu时出现win7无法启动?
- Java中对象序列化与反序列化
- Properties类与.properties文件
- android不透明度16进制值
- 开发手记9.14
- webservice 中根据xml 片段,反转xsd 文件,生成java 对象
- VS2013打包部署(图解)
- Java中List的排序方法