1. 程式人生 > 實用技巧 >牛客多校2020 第三場-H Sort the Strings Revision(笛卡爾樹+分治

牛客多校2020 第三場-H Sort the Strings Revision(笛卡爾樹+分治

題意:https://ac.nowcoder.com/acm/contest/5668/H

給你一些修改操作讓你給所有改完後的結果排個序

思路:

很容易想到分治

建立笛卡爾樹後左右跑跑,先跑變小的,一開始dfs沒想好寫了半天,其實按照分配 rank 的思路去寫就行了,先分配左邊的,有小的再分配小的

 1 ll n;
 2 int son[N][2];
 3 ll p[N],d[N],ans[N];
 4 int stak[N];
 5 
 6 void dfs(int l,int r,int x,int rk)
 7 {
 8     if(l>r)return;
 9     if(l==r)
10 { 11 ans[l]=rk; 12 return; 13 } 14 if(p[x]==inf||d[x]>p[x]%10) 15 { 16 dfs(l,x-1,son[x][0],rk); 17 dfs(x,r,son[x][1],rk+x-l); 18 } 19 else 20 { 21 dfs(x,r,son[x][1],rk); 22 dfs(l,x-1,son[x][0],rk+r-x+1); 23 } 24 return
; 25 } 26 27 signed main() 28 { 29 int T; 30 sc("%lld",&T); 31 while(T--) 32 { 33 sc("%lld",&n); 34 ll p_seed,p_a,p_b,p_mod,d_seed,d_a,d_b,d_mod; 35 scanf("%lld%lld%lld%lld",&p_seed,&p_a,&p_b,&p_mod); 36 scanf("%lld%lld%lld%lld"
,&d_seed,&d_a,&d_b,&d_mod); 37 for(int i=0;i<n;i++) p[i]=i; 38 for(int i=1;i<n;i++){ 39 swap(p[p_seed%(i+1)],p[i]); 40 p_seed=(1ll*p_seed*p_a+1ll*p_b)%p_mod; 41 } 42 for(int i=0;i<n;i++){ 43 d[i]=d_seed%10; 44 d_seed=(1ll*d_seed*d_a+1ll*d_b)%d_mod; 45 } 46 47 for(int i=n+1;i>1;--i) 48 { 49 p[i]=p[i-2],d[i]=d[i-2]; 50 if(p[i]%10==d[i])p[i]=inf; 51 } 52 n++; 53 p[1]=d[1]=inf; 54 55 int top=0; 56 for(int i=1;i<=n;++i) 57 { 58 while(top&&p[i]<p[stak[top]]) 59 son[i][0]=stak[top--]; 60 if(top) 61 son[stak[top]][1]=i; 62 stak[++top]=i; 63 } 64 dfs(1,n,stak[1],0); 65 // for(int i=1;i<=n;++i) 66 // pr("%lld%c",ans[i]," \n"[i==n]); 67 int res=0,temp=1; 68 for(int i=1;i<=n;++i) 69 res=(res+ans[i]*temp%mod)%mod,temp=temp*10000019%mod; 70 pr("%lld\n",res); 71 // pr("%lld\n",stak[1]); 72 } 73 return 0; 74 }