[BZOJ1125]Poc

Posted jefflyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1125]Poc相关的知识,希望对你有一定的参考价值。

哈希一下每一个字符串,对每一个哈希值$s$建一棵treap保存(所有哈希值等于$s$的字符串)的下标

每个节点维护一个标记表示这个节点在任何时点,它所处的treap的节点数的最大值(就是答案)

每次修改就暴力重新算哈希值,删除,插入后打一个标记

同一个字符串交换字符要特殊处理

#include<stdio.h>
#include<stdlib.h>
#include<map>
using namespace std;
#define ull unsigned long long
map<ull,int>rt;
map<ull,int>::iterator it;
int fix[1010],l[1010],r[1010],v[1010],p[1010],siz[1010],len;
ull hash_[1010];
char s[1010][110];
struct pr{
	int l,r;
	pr(int a=0,int b=0){l=a;r=b;}
};
void gao(int x,int d){
	v[x]=max(v[x],d);
	p[x]=max(p[x],d);
}
void pushdown(int x){
	if(p[x]){
		if(l[x])gao(l[x],p[x]);
		if(r[x])gao(r[x],p[x]);
		p[x]=0;
	}
}
void pushup(int x){
	siz[x]=siz[l[x]]+siz[r[x]]+1;
}
pr split(int x,int k){
	if(x==0)return pr();
	pushdown(x);
	pr s;
	if(k<=siz[l[x]]){
		s=split(l[x],k);
		l[x]=s.r;
		s.r=x;
	}else{
		s=split(r[x],k-siz[l[x]]-1);
		r[x]=s.l;
		s.l=x;
	}
	pushup(x);
	return s;
}
int merge(int x,int y){
	if(x==0)return y;
	if(y==0)return x;
	if(fix[x]<fix[y]){
		pushdown(x);
		r[x]=merge(r[x],y);
		pushup(x);
		return x;
	}else{
		pushdown(y);
		l[y]=merge(x,l[y]);
		pushup(y);
		return y;
	}
}
int lt(int x,int p){
	int s=0;
	while(x){
		if(x<p){
			s+=siz[l[x]]+1;
			x=r[x];
		}else
			x=l[x];
	}
	return s;
}
void gethash(int p){
	ull h=0;
	for(int i=1;i<=len;i++)h=h*2333ll+(ull)s[p][i];
	hash_[p]=h;
}
void dfs(int x){
	pushdown(x);
	if(l[x])dfs(l[x]);
	if(r[x])dfs(r[x]);
}
int main(){
	srand(19260817);
	int n,m,i,a,b,c,d;
	pr s1,s2;
	scanf("%d%d%d",&n,&len,&m);
	for(i=1;i<=n;i++){
		scanf("%s",s[i]+1);
		gethash(i);
		fix[i]=rand();
		siz[i]=v[i]=1;
		rt[hash_[i]]=merge(rt[hash_[i]],i);
	}
	for(it=rt.begin();it!=rt.end();it++)gao(it->second,siz[it->second]);
	while(m--){
		scanf("%d%d%d%d",&a,&b,&c,&d);
		if(a==c){
			s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
			s2=split(s1.r,1);
			rt[hash_[a]]=merge(s1.l,s2.r);
			swap(s[a][b],s[a][d]);
			gethash(a);
			s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
			rt[hash_[a]]=merge(s1.l,merge(a,s1.r));
			gao(rt[hash_[a]],siz[rt[hash_[a]]]);
		}else{
			s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
			s2=split(s1.r,1);
			rt[hash_[a]]=merge(s1.l,s2.r);
			s1=split(rt[hash_[c]],lt(rt[hash_[c]],c));
			s2=split(s1.r,1);
			rt[hash_[c]]=merge(s1.l,s2.r);
			swap(s[a][b],s[c][d]);
			gethash(a);
			s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
			rt[hash_[a]]=merge(s1.l,merge(a,s1.r));
			gao(rt[hash_[a]],siz[rt[hash_[a]]]);
			gethash(c);
			s1=split(rt[hash_[c]],lt(rt[hash_[c]],c));
			rt[hash_[c]]=merge(s1.l,merge(c,s1.r));
			gao(rt[hash_[c]],siz[rt[hash_[c]]]);
		}
	}
	for(it=rt.begin();it!=rt.end();it++){
		if(it->second)dfs(it->second);
	}
	for(i=1;i<=n;i++)printf("%d\n",v[i]);
}

以上是关于[BZOJ1125]Poc的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1125[POI2008]Poc hash+map+SBT

关于poc脚本的一些问题

BZOJ 题目整理

BZOJ 1019--汉诺塔(DP)

PAT1125:Chain the Ropes

P1125 笨小猴