日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bzoj-1031 字符加密Cipher

發布時間:2023/12/20 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bzoj-1031 字符加密Cipher 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:

給出一個字符串,求將其所有循環串排序之后,每個串的最后一個字符;

字符串長度<=100000;


題解:

后綴數組裸題。。吧

學長拿這個當例題我還差點不會做。。。

反正就是把字符串倍增之后求后綴數組;

然后按后綴數組來掃一遍求解;

難點就是后綴排序(廢話!);

這里用的是O(nlogn)的倍增+基數排序方法;

模板純手寫。。一堆for循環也是有毒。。

原理上就是利用倍增的思想,將每次的排序轉化為二元組的排序問題;

而二元組的排序問題可以利用基數排序O(n)解決而已;

寫代碼的時候好費勁啊。。。碼力果然不夠強;

30行模板4數組,Orz PoPoQQQ 60行SA;


代碼:


#include<stdio.h> #include<string.h> #include<algorithm> #define N 210000 #define S 256 using namespace std; char str[N]; int rank[N],tr[N],hash[N],sa[N]; int main() {int n,m,j,k,cnt;register int i;scanf("%s",str);n=strlen(str);memcpy(str+n,str,sizeof(char)*n);n<<=1;for(i=0;i<n;i++) hash[str[i]]++;for(i=1,cnt=0;i<S;i++) if(hash[i]) tr[i]=++cnt;for(i=1;i<S;i++) hash[i]=hash[i-1]+hash[i];for(i=0;i<n;i++) rank[i]=tr[str[i]];for(i=0;i<n;i++) sa[--hash[str[i]]]=i;for(k=2;k<=n;k<<=1){memset(hash,0,sizeof(hash));for(i=0;i<n;i++) hash[rank[i]]++;for(i=1;i<=n;i++) hash[i]=hash[i]+hash[i-1];for(i=n-1;i>=0;i--) if(sa[i]>=(k>>1))tr[sa[i]-(k>>1)]=--hash[rank[sa[i]-(k>>1)]];for(i=1;i<=(k>>1);i++) tr[n-i]=--hash[rank[n-i]];for(i=0;i<n;i++) sa[tr[i]]=i;for(i=1,cnt=0;i<n;i++)if(rank[sa[i-1]]==rank[sa[i]]&&rank[sa[i-1]+(k>>1)]==rank[sa[i]+(k>>1)]) tr[sa[i]]=tr[sa[i-1]];else tr[sa[i]]=++cnt;memcpy(rank,tr,sizeof(tr));if(cnt==n-1)break;}for(i=0;i<n;i++){if(sa[i]<(n>>1))printf("%c",str[sa[i]+(n>>1)-1]);}return 0; }

總結

以上是生活随笔為你收集整理的bzoj-1031 字符加密Cipher的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。