码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ1125]Poc

时间:2018-01-16 00:41:37      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:字符   else   namespace   节点   swa   and   merge   ash   特殊   

哈希一下每一个字符串,对每一个哈希值$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

标签:字符   else   namespace   节点   swa   and   merge   ash   特殊   

原文地址:https://www.cnblogs.com/jefflyy/p/8290000.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!