1. 程式人生 > >[bzoj1125][動態開點線段樹][雜湊]Poc

[bzoj1125][動態開點線段樹][雜湊]Poc

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

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; }