【BZOJ1031】字符加密Cipher(后缀数组)

题意:将一个长度为2n(复制粘贴后)的字符串的所有长度为n的后缀从小到大排序,并依次输出它们的最后一个字母。

n<=100000

思路:裸SA,模板真难背

P党不得不写成C++风格

 1 var ch:array[0..300000]of char;
 2     a,x,y,wc,wd,sa:array[0..300000]of longint;
 3     n,i,m:longint;
 4     tmp:char;
 5
 6 function cmp(a,b,l:longint):boolean;
 7 begin
 8  exit((y[a]=y[b])and(y[a+l]=y[b+l]));
 9 end;
10
11 procedure swap(var x,y:longint);
12 var t:longint;
13 begin
14  t:=x; x:=y; y:=t;
15 end;
16
17 procedure getsa;
18 var i,j,p:longint;
19 begin
20  for i:=0 to n-1 do
21  begin
22   x[i]:=a[i];
23   inc(wc[a[i]]);
24  end;
25  for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
26  for i:=n-1 downto 0 do
27  begin
28   dec(wc[x[i]]);
29   sa[wc[x[i]]]:=i;
30  end;
31
32  j:=1; p:=1;
33  while p<n do
34  begin
35   p:=0;
36   for i:=n-j to n-1 do
37   begin
38    y[p]:=i; inc(p);
39   end;
40   for i:=0 to n-1 do
41    if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end;
42  // for i:=0 to n-1 do writeln(y[i]);
43   for i:=0 to n-1 do wd[i]:=x[y[i]];
44   for i:=0 to m do wc[i]:=0;
45   for i:=0 to n-1 do inc(wc[wd[i]]);
46   for i:=1 to m do wc[i]:=wc[i-1]+wc[i];
47   for i:=n-1 downto 0 do
48   begin
49    dec(wc[wd[i]]);
50    sa[wc[wd[i]]]:=y[i];
51   end;
52
53   for i:=0 to n do swap(x[i],y[i]);
54
55   p:=1; x[sa[0]]:=0;
56   for i:=1 to n-1 do
57   begin
58    if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1
59     else begin x[sa[i]]:=p; inc(p); end;
60   end;
61
62   j:=j*2;
63   m:=p;
64  end;
65 end;
66
67
68 begin
69   assign(input,‘bzoj1031r.in‘); reset(input);
70   assign(output,‘bzoj1031r.out‘); rewrite(output);
71  while not eoln do
72  begin
73   read(tmp);
74   inc(n);
75   ch[n]:=tmp;
76  end;
77  for i:=1 to n do a[i-1]:=ord(ch[i]);
78  for i:=n to n*2-1 do a[i]:=a[i-n];
79  n:=n*2+1; m:=300;
80  getsa;
81  for i:=1 to n-1 do
82   if sa[i]<(n>>1) then
83   begin
84    if sa[i]=0 then write(chr(a[n-2]))
85     else write(chr(a[sa[i]-1]));
86   end;
87  close(input);
88 close(output);
89
90
91 end.
时间: 2024-11-24 04:18:24

【BZOJ1031】字符加密Cipher(后缀数组)的相关文章

[JSOI2007][BZOJ1031] 字符加密Cipher|后缀数组

1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4296  Solved: 1746[Submit][Status][Discuss] Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 0

【BZOJ-1031】字符加密Cipher 后缀数组

1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5504  Solved: 2277[Submit][Status][Discuss] Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 0

BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组

1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6014  Solved: 2503[Submit][Status][Discuss] Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 0

BZOJ 1031 JSOI 2007 字符加密Cipher 后缀数组

题目大意:给出一个字符串,循环字符串的起始位置,可以得到length个不同的字符串,问把这些字符串排序之后每一个字符串的第一位是什么. 思路:后缀数组裸题,只需要将整个字符串倍增,然后求一次sa. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 200010 using namespace std; char s[M

[BZOJ1031] [JSOI2007] 字符加密Cipher (后缀数组)

Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是 突然想出来

bzoj 1031 [JSOI2007]字符加密Cipher 后缀数组模板

题目链接 题目描述 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是突然想出来的,那

BZOJ_1031_[JSOI2007]字符加密Cipher_后缀数组

Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0把它们按照字符串的大小排序:07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容易破解,鉴于这是 突然想出来

[BZOJ1031] 字符加密Cipher

被wsh大爷拉入坑,然而我会说他现在在睡觉? 题意:求一个循环同构的字符串的按字典序排序后末尾的字符的序列 飒飒飒 我们把这个字符串粘(nian)两遍,然后飒飒飒就好啦 可以这么轻易是因为对于一个倍长后的字符串,如果我们不能仅按前n位就将这个字符串排序, 当且仅当这个字符串的某些后缀的完全相同,然而这样就算不排序也不会影响答案,像这样:飒飒飒,或SASASA(赭石在麦门 上代码,,,代码好惨QAQ 1 #include<bits/stdc++.h> 2 using namespace std;

大视野 1031 字符加密Cipher(后缀数组)

字符加密Cipher Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO 07JSOI 7JSOI0 把它们按照字符串的大小排序: 07JSOI 7JSOI0 I07JSO JSOI07 OI07JS SOI07J 读出最后一列字符:I0O7SJ,就是加密后的字符串(其实这个加密手段实在很容

BZOJ 题目1031: [JSOI2007]字符加密Cipher(后缀数组sa简单应用)

1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4318  Solved: 1760 [Submit][Status][Discuss] Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作: JSOI07 SOI07J OI07JS I07JSO