NOIP提高模擬-20181016-T3-長者
阿新 • • 發佈:2018-12-15
寫在前面
考場上看到本題根本不會,下來以後看了看題解發現是一道主席樹+hash的題目,然而完全不會,所以說去認真的學習了主席樹之後,成功的A掉了這道題目。
Solution
做法
按照題目存下所有長者對應的字串,然後暴力比較兩個字串的大小,快速排序即可。 時間複雜度 。
做法
可以利用雜湊做到比較兩個字串的大小。 具體方法是雜湊結合二分找到第一個字串不同的位置,然後比較這個位置的大小。 結合快速排序,時間複雜度
對於另外
此時形成一棵二叉樹,任意長者的字串與 1 號長者的字串最多隻有 處不同。這 說明任意兩個字串最多也只有 處不同。
於是我們只用比較這 個不同的位置,結合快速排序可以做到 。
做法
雜湊二分的方法其實就是不斷的詢問字串的某一部分的雜湊值。
我們可以用線段樹來維護雜湊值,那麼每次修改一個位置只需要把父親的線段樹改一個位置。 利用主席樹來維護,比較的時候也從主席樹的兩個根開始遞迴比較,可以做到 。 Talk is Cheap, Show You the Code:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
int read(){
int sum=0,neg=1;
char c=getchar();
while(c>'9'||c<'0'&& c!='-') c=getchar();
if(c=='-') neg=-1,c=getchar();
while(c>='0'&&c<='9') sum=(sum<<1)+(sum<<3)+c-'0',c=getchar();
return sum*neg;
}
const int N=1e5+50;
const ULL base=31;
int n,m; char s[N];
int rt[N],lc[N*40],rc[N*40],len[N*40],p[N],tot;
ULL pw[N],sum[N*40];
inline void build(int &k,int l,int r){
k=++tot; len[k]=r-l+1;
if(l==r) {sum[k]=s[l]; return;}
int mid=(l+r)>>1;
build(lc[k],l,mid);
build(rc[k],mid+1,r);
sum[k]=sum[lc[k]]+sum[rc[k]]*pw[len[lc[k]]];
}
inline void copy(int &x,int y){
x=++tot;
lc[x]=lc[y];
rc[x]=rc[y];
len[x]=len[y];
sum[x]=sum[y];
}
inline void inc(int x,int &y,int l,int r,int p,int v){
copy(y,x);
if(l==r){
sum[y]=v; return;
}
int mid=(l+r)>>1;
if(p<=mid) inc(lc[x],lc[y],l,mid,p,v);
else inc(rc[x],rc[y],mid+1,r,p,v);
sum[y]=sum[lc[y]]+sum[rc[y]]*pw[len[lc[y]]];
}
inline int cmp(int x,int y,int l,int r){
if(l==r){
return (sum[x]<sum[y])?-1:1;
}
int mid=(l+r)>>1;
if(sum[lc[x]]!=sum[lc[y]]) return cmp(lc[x],lc[y],l,mid);
else return cmp(rc[x],rc[y],mid+1,r);
}
inline bool comp(const int &i,const int &j){
if(sum[rt[i]]==sum[rt[j]]) return i<j;
return cmp(rt[i],rt[j],1,m)<0;
}
int main(){
n=read(), m=read();
scanf("%s",s+1);
for(int i=pw[0]=1;i<=m;++i) pw[i]=pw[i-1]*base;
build(rt[1],1,m);
for(int i=2;i<=n;i++){
int f=read(), pos=read();
scanf("%s",s+1);
inc(rt[f],rt[i],1,m,pos,s[1]);
}
for(int i=1;i<=n;i++) p[i]=i;
sort(p+1,p+n+1,comp);
for(int i=1;i<=n;i++) printf("%d ",p[i]);
}