bzoj1031 [JSOI2007] Character Encryption Cipher

Description


 JS students who like to study problems have recently become obsessed with thinking about encryption methods. One day, he suddenly came up with what he thought was the ultimate encryption method 
: arrange the information to be encrypted in a circle, and obviously, they can be read in many different ways. For example, the following figure can be read as: 
write picture description here

JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0 Sort them according to the size of the string: 07JSOI 7JSOI0 I07JSO JSOI07
OI07JS SOI07J Read the last column of characters: I0O7SJ, which is the encrypted string (in fact, this encryption method is really easy to crack, since this is a 
sudden thought out, then ^^). However, if the string you want to encrypt is too long, can you write a program to do this?

For 100% of the data string length does not exceed 100000.

Solution


The suffix array SA of the first question of this konjac is to commemorate 
the copy of the original string and add it to the back, all the suffixes that run out are sorted in order, and 
the board a that comes with the ok film after taking the last digit ah b ah c d ah the mess is a little dizzy, but I can't think of a better alternative to 
spicy chicken csdn, I'm stuck

Code


#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define rep(i,st,ed)for(int i=st;i<=ed;++i)
#define drp(i,st,ed)for(int i=st;i>=ed;--i)
#define fill(x,t) memset(x,t,sizeof(x))
#define copy(x,t) memcpy(x,t,sizeof(x))

constint N=200005;

int rank[N],sa[N],h[N];
int b[N],c[N],d[N];

char s[N],ans[N];

void get_sa(int n,int m){
    rep(i,0,m) b[i]=0;
    rep(i,1,n) b[s[i]]++;
    rep(i,1,m) b[i]+=b[i-1];
    drp(i,n,1) c[b[s[i]]--]=i;
int t=0;
    rep(i,1,n){
if(s[c[i]]!=s[c[i-1]]) t++;
        rank[c[i]]=t;
}
int j=1;
while(j<=n){
        rep(i,0,n) b[i]=0;
        rep(i,1,n) b[rank[i+j]]++;
        rep(i,1,n) b[i]+=b[i-1];
        drp(i,n,1) c[b[rank[i+j]]--]=i;
        rep(i,0,n) b[i]=0;
        rep(i,1,n) b[rank[i]]++;
        rep(i,1,n) b[i]+=b[i-1];
        drp(i,n,1) d[b[rank[c[i]]]--]=c[i];
int t=0;
        rep(i,1,n){
if(rank[d[i]]!=rank[d[i-1]]||rank[d[i]]==rank[d[i-1]]&&rank[d[i]+j]!=rank[d[i-1]+j]) t++;
            c[d[i]]=t;
}
        rep(i,1,n) rank[i]=c[i];
if(t==n)break;
        j*=2;
}
    rep(i,1,n)
        sa[rank[i]]=i;
}

void get_height(int n){
int k=0;
    rep(i,1,n){
if(k) k--;
int j=sa[rank[i]-1];
while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
        h[rank[i]]=k;
}
}

int main(void){
scanf("%s", s);int len=strlen(s),m=0;
    drp(i,len,1){
        s[i+len]=s[i]=s[i-1];
        m=std:: max(m,(int)s[i]);
}
    get_sa(len*2,m);
    get_height(len*2);
int j=0;
    rep(i,1,len*2)if(sa[i]<=len) ans[++j]=s[sa[i]+len-1];
    rep(i,1,len)printf("%c",ans[i]);
return0;
}

 This article is reproduced from: http://www.javaxxz.com/thread-359193-1-1.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326090061&siteId=291194637