[bzoj1125][动态开点线段树][哈希]Poc

版权声明:蒟蒻的blog... https://blog.csdn.net/Rose_max/article/details/84938290

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个数,在交换车厢的某个时刻,与该车颜色完全相同的火车最多数目。

Sample Input

5 6 7

ababbd

abbbbd

aaabad

扫描二维码关注公众号,回复: 4511629 查看本文章

caabbd

cabaad

2 3 5 4

5 3 5 5

3 5 2 2

1 2 4 3

2 2 5 1

1 1 3 3

4 1 5 6

Sample Output

3

3

3

2

3

题解

开1000棵线段树维护一下哈希值
然后你就发现不同哈希值总共不会超过10W个
开个vector记录一下每个串变成了什么哈希值,在什么时候变成的
动态开点线段树记录这个哈希值在这里开始是这一个值,直到碰到下一个值之前都还是这个值
最后扫一遍就行了…

//#orz tyb
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<ctime>
#include<map>
#include<bitset>
#define LL long long
#define mp(x,y) make_pair(x,y)
#define ULL unsigned long long
using namespace std;
inline int read()
{
	int f=1,x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int stack[20];
inline void write(int x)
{
	if(x<0){putchar('-');x=-x;}
    if(!x){putchar('0');return;}
    int top=0;
    while(x)stack[++top]=x%10,x/=10;
    while(top)putchar(stack[top--]+'0');
}
inline void pr1(int x){write(x);putchar(' ');}
inline void pr2(int x){write(x);putchar('\n');}
const LL mod=1e9+7;
const ULL base=233;
ULL temp[2100];
int ma[2005][105];
struct segtree1
{
	ULL mx[1100][110*8];
	void modify(int now,int l,int r,int p,int c,int op)
	{
//		if(l==r){mx[op][now]=c%mod;return ;}
		if(l==r){mx[op][now]=c;return ;}
		int mid=(l+r)/2,lc=now<<1,rc=now<<1|1;
		if(p<=mid)modify(lc,l,mid,p,c,op);
		else modify(rc,mid+1,r,p,c,op);
//		mx[op][now]=(mx[op][lc]*temp[r-mid+1]%mod+mx[op][rc])%mod;
		mx[op][now]=mx[op][lc]*temp[r-mid]+mx[op][rc];
	}
	void buildtree(int now,int l,int r,int op)
	{
		if(l==r){mx[op][now]=ma[op][l]%mod;return ;}
		int mid=(l+r)/2,lc=now<<1,rc=now<<1|1;
		buildtree(lc,l,mid,op);buildtree(rc,mid+1,r,op);
//		mx[op][now]=(mx[op][lc]*temp[r-mid+1]%mod+mx[op][rc])%mod;
		mx[op][now]=mx[op][lc]*temp[r-mid]+mx[op][rc];	
	}
}seg1;
map<ULL,int> mp;
map<ULL,int> rt;
struct segtree2
{
	int lc[210000*30],rc[210000*30],mx[210000*30],trlen;
	void modify(int &now,int l,int r,int p,int c)
	{
		if(!now)now=++trlen;
		if(l==r){mx[now]=c;return ;}
		int mid=(l+r)/2;
		if(p<=mid)modify(lc[now],l,mid,p,c);
		else modify(rc[now],mid+1,r,p,c);
		mx[now]=max(mx[lc[now]],mx[rc[now]]);
	}
	int query(int now,int l,int r,int ql,int qr)
	{
		if(!now)return 0;
		if(l>=ql&&r<=qr)return mx[now];
		int mid=(l+r)/2;
		if(qr<=mid)return query(lc[now],l,mid,ql,qr);
		else if(mid+1<=ql)return query(rc[now],mid+1,r,ql,qr);
		else return max(query(lc[now],l,mid,ql,mid),query(rc[now],mid+1,r,mid+1,qr));
	}
}seg2;
int n,L,m;
vector<pair<ULL,int> > vec[1005];
char ch[1005];
int answer[1005];
int main()
{
//	freopen("a.in","r",stdin);
//	freopen("a.out","w",stdout);
	temp[0]=1;for(int i=1;i<=2000;i++)temp[i]=temp[i-1]*base;
	n=read();L=read();m=read();
	for(int i=1;i<=n;i++)
	{
		scanf("%s",ch+1);
		for(int j=1;j<=L;j++)ma[i][j]=ch[j]-'a'+1;
		seg1.buildtree(1,1,L,i);
		vec[i].push_back(mp(seg1.mx[i][1],1));
	}
	for(int i=1;i<=n;i++)mp[seg1.mx[i][1]]++;
	for(int i=1;i<=n;i++)seg2.modify(rt[seg1.mx[i][1]],1,m,1,mp[seg1.mx[i][1]]);
	
//	printf("%d CHECKER \n",0);
//	for(int i=1;i<=n;i++)printf("id= %d  hash=%llu  sum= %d\n",i,seg1.mx[i][1],mp[seg1.mx[i][1]]);
//	for(int i=1;i<=n;i++)answer[i]=max(answer[i],mp[seg1.mx[i][1]]);
	
	for(int tt=1;tt<=m;tt++)
	{
		int a=read(),b=read(),c=read(),d=read();
		mp[seg1.mx[a][1]]--;
		if(a!=c)mp[seg1.mx[c][1]]--;
		seg2.modify(rt[seg1.mx[a][1]],1,m,tt,mp[seg1.mx[a][1]]);
		seg2.modify(rt[seg1.mx[c][1]],1,m,tt,mp[seg1.mx[c][1]]);
		
		
		seg1.modify(1,1,L,b,ma[c][d],a);seg1.modify(1,1,L,d,ma[a][b],c);
		
		
		mp[seg1.mx[a][1]]++;
		if(a!=c)mp[seg1.mx[c][1]]++;
		
//		printf("%d CHECKER \n",tt);
//		for(int i=1;i<=n;i++)printf("id= %d  hash=%llu  sum= %d\n",i,seg1.mx[i][1],mp[seg1.mx[i][1]]);
//		for(int i=1;i<=n;i++)answer[i]=max(answer[i],mp[seg1.mx[i][1]]);
		
		
		seg2.modify(rt[seg1.mx[a][1]],1,m,tt,mp[seg1.mx[a][1]]);
		seg2.modify(rt[seg1.mx[c][1]],1,m,tt,mp[seg1.mx[c][1]]);
		
		swap(ma[a][b],ma[c][d]);
		vec[a].push_back(mp(seg1.mx[a][1],tt));
		if(a!=c)vec[c].push_back(mp(seg1.mx[c][1],tt));
	}
	
	for(int i=1;i<=n;i++)
	{
		int ln=vec[i].size();
		for(int j=0;j<ln;j++)
		{
			int st=vec[i][j].second,ed;ULL pa=vec[i][j].first;
			if(j==ln-1)ed=m;
			else ed=vec[i][j+1].second-1;
			answer[i]=max(answer[i],seg2.query(rt[pa],1,m,st,ed));
		}
	}
	for(int i=1;i<=n;i++)pr2(answer[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Rose_max/article/details/84938290