提出 #958420
ソースコード 拡げる
import java.io.PrintWriter;
import java.util.Scanner;
/**
* http://code-festival-2016-qualb.contest.atcoder.jp/tasks/codefestival_2016_qualB_e
*
* @author Cummin
*/
public class Main {
static int N ; // 1<= N <= 100000
static int Q ; // 1<= Q <= 100000
static int K[] ;
static char S[][] ; // Σ|S| < 400000文字
static char P[][];
static PTNode root ;
static int node_no = 0 ; // 採番用
static PTNode node_pool[] ;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
S = new char[N][] ;
for (int i=0 ; i<N ;i++) {
S[i] =sc.next().toCharArray() ;
}
Q = sc.nextInt();
K = new int[Q] ;
P = new char[Q][] ;
for (int i=0 ; i<Q; i++) {
K[i] = sc.nextInt() -1 ;
P[i] = sc.next().toCharArray() ;
}
///
int size= 0 ;
for (int i=0 ; i<N ; i++) {
size = size + S[i].length +1;
}
node_pool = new PTNode[size];
make_tree() ;
/** /
tree_dump() ;
System.out.println() ;
/**/
////// 出力 ////////////////
PrintWriter out = new PrintWriter(System.out);
for (int i = 0; i < Q; i++) {
out.println(Solve(root, K[i], P[i]));
}
out.flush();
////////////////////////////
}
/**/
/////////// tree dump /////////////
static void tree_dump() {
PTNode cn ;
for (int n= 0 ; n< node_pool.length; n++) {
if (node_pool[n]==null) return ;
cn = node_pool[n] ;
if (cn.s==null) {
System.out.printf("\n Node=%d, char=%s, link_cnt=%d, leaf=%d ",
cn.number, "-", cn.link_cnt, cn.leaf);
} else {
System.out.printf("\n Node=%d, char=%s, link_cnt=%d, leaf=%d ",
cn.number, String.valueOf(cn.s), cn.link_cnt, cn.leaf);
}
for (int i=0 ; i<26; i++){
if (cn.next_node[i]==0) continue ;
System.out.printf( "child=%d, ", cn.next_node[i]) ;
}
}
}
////////////////////////////////
/**/
//////////////////////////////////////
static class PTNode { // Patricia Trie // 親がindexを持つ。親のnodeからchild_nodeを操作する
char s[] ; // ponter to original string
////////
int number ;
//int index ; // ノードの下のNodeに該当する文字があるかのIndex
int link_cnt ;
int next_node[] = new int[26] ; // 次のレベルへのリンク
int leaf ;
PTNode() {
this.number = node_no ;
node_no ++ ;
// System.out.printf("PTNode (New)= %d \n",number) ;
}
}
static int compare(char a[], char b[]) { // マッチしない位置を返す // 全体がマッチすると、min(a.length, b.length)+1を返す
int len = a.length;
if (len==0) return 0 ;
if (len>b.length) len = b.length;
for (int i=0 ; i<len ; i++){
if (a[i]!=b[i]) return i+1 ;
}
return len +1 ;
}
static void insert(PTNode node, char in[]) {
// 子供のエントリーは一文字目から始まるものがない場合->nodeの追加
if (node.next_node[in[0]-'a'] ==0) {
PTNode p = new PTNode() ;
node_pool[p.number] = p ;
p.s = in ;
//
node.next_node[in[0]-'a']=p.number ;
node.link_cnt ++ ;
p.leaf = 1 ;
return ;
}
// inの1文字目から始まるエントリーが子供にある
PTNode child_node = node_pool[node.next_node[in[0]-'a']];
if (child_node==null) System.out.printf("Child node match ERROR\n") ;
int pos = compare(child_node.s, in) ; // 全体がマッチすると、length+1を返す
if ((pos> child_node.s.length) && (in.length == child_node.s.length)) {
// 全体がマッチし、かつ、同じ長さ==>Nodeは追加せずにLeafだけ追加
node.link_cnt ++ ;
child_node.leaf = 1 ;
return ;
}
if ((pos > child_node.s.length)&&(in.length >child_node.s.length)) {
// 全体がマッチし、かつ、inが長い -> 長い部分を、子供として追加する
char in2[] = new char[in.length - pos + 1];
System.arraycopy(in, pos-1, in2, 0, in2.length) ;
insert(child_node, in2) ;
node.link_cnt++ ;
return ;
}
// 分割が必要な場合
char head[] = new char[pos-1];
System.arraycopy(child_node.s, 0, head, 0, pos-1) ;
char tail[] = new char[child_node.s.length-pos +1] ;
System.arraycopy(child_node.s, pos-1, tail, 0, tail.length);
// マッチした長さがsより短い場合、元のノードを分割する
PTNode temp = child_node ;
node.next_node[child_node.s[0]-'a'] = 0 ; // remove(child_node)
PTNode new_n = new PTNode() ; // これを前に挿入する
node_pool[new_n.number] = new_n ;
new_n.s = head ;
node.next_node[head[0]-'a']=new_n.number ; // add(new_node) [replace with new node]
new_n.link_cnt = temp.link_cnt + temp.leaf ; //
temp.s = tail ;
new_n.next_node[tail[0]-'a']=temp.number ; // add(temp_node) after new node
// inはsの部分文字列 -> 挿入したノードにLeafを追加
if((pos-1)==in.length) {
new_n.leaf = 1;
node.link_cnt++; // 最後に親を更新する
} else {
// 相違する部分のノードを追加
char tail2[] = new char[in.length-pos+1];
System.arraycopy(in, pos-1, tail2, 0, tail2.length);
PTNode new_n2 = new PTNode();
node_pool[new_n2.number] = new_n2 ;
new_n2.s = tail2 ;
new_n.next_node[tail2[0]-'a'] = new_n2.number ;
new_n.link_cnt++ ;
new_n2.leaf = 1;
node.link_cnt++; // 最後に親を更新する
}
}
//////////////////////////////////////
static int power_2[] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,1<<13, 1<<14, 1<<15, 1<<16, 1<<17,
1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23, 1<<24, 1<<25};
static void make_tree() {
root = new PTNode() ;
node_pool[root.number] = root ;
for (int i=0 ; i<N; i++) {
insert(root, S[i]) ;
}
}
static int Solve(PTNode current_node, int k, char[] ptn) {
int cnt = 0;
for (int i = 0; i < S[k].length;) {
OUTER:
for (int j = 0; j < 26; j++) {
if (current_node.next_node[ptn[j] - 'a'] == 0) {
continue;
}
int child_node_num = node_pool[current_node.next_node[ptn[j] - 'a']].number;
int pt = S[k][i] - ptn[j];
if (pt != 0) {
cnt = cnt + node_pool[child_node_num].link_cnt + node_pool[child_node_num].leaf;
continue;
}
if (pt == 0) {
cnt = cnt + node_pool[child_node_num].leaf;
i = i + node_pool[child_node_num].s.length;
current_node = node_pool[child_node_num];
break OUTER;
}
}
}
return cnt;
}
}
提出情報
ジャッジ結果
| セット名 |
Sample |
All |
| 得点 / 配点 |
0 / 0 |
1100 / 1100 |
| 結果 |
|
|
| セット名 |
テストケース |
| Sample |
s1.txt, s2.txt |
| All |
01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, 40.txt, s1.txt, s2.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 01.txt |
AC |
1065 ms |
93508 KiB |
| 02.txt |
AC |
1026 ms |
92756 KiB |
| 03.txt |
AC |
1015 ms |
96732 KiB |
| 04.txt |
AC |
1062 ms |
92048 KiB |
| 05.txt |
AC |
930 ms |
83856 KiB |
| 06.txt |
AC |
1017 ms |
59764 KiB |
| 07.txt |
AC |
766 ms |
58064 KiB |
| 08.txt |
AC |
783 ms |
59328 KiB |
| 09.txt |
AC |
714 ms |
57952 KiB |
| 10.txt |
AC |
850 ms |
67468 KiB |
| 11.txt |
AC |
920 ms |
82560 KiB |
| 12.txt |
AC |
1022 ms |
99056 KiB |
| 13.txt |
AC |
1147 ms |
98108 KiB |
| 14.txt |
AC |
936 ms |
60356 KiB |
| 15.txt |
AC |
864 ms |
60640 KiB |
| 16.txt |
AC |
943 ms |
58300 KiB |
| 17.txt |
AC |
801 ms |
61224 KiB |
| 18.txt |
AC |
2011 ms |
92136 KiB |
| 19.txt |
AC |
1985 ms |
91060 KiB |
| 20.txt |
AC |
2611 ms |
92592 KiB |
| 21.txt |
AC |
2555 ms |
91344 KiB |
| 22.txt |
AC |
2629 ms |
93868 KiB |
| 23.txt |
AC |
1249 ms |
100036 KiB |
| 24.txt |
AC |
925 ms |
82196 KiB |
| 25.txt |
AC |
1030 ms |
99292 KiB |
| 26.txt |
AC |
1617 ms |
152884 KiB |
| 27.txt |
AC |
923 ms |
59092 KiB |
| 28.txt |
AC |
942 ms |
59496 KiB |
| 29.txt |
AC |
844 ms |
63796 KiB |
| 30.txt |
AC |
1404 ms |
87252 KiB |
| 31.txt |
AC |
788 ms |
59560 KiB |
| 32.txt |
AC |
786 ms |
56916 KiB |
| 33.txt |
AC |
799 ms |
59708 KiB |
| 34.txt |
AC |
740 ms |
59576 KiB |
| 35.txt |
AC |
765 ms |
60976 KiB |
| 36.txt |
AC |
1180 ms |
90652 KiB |
| 37.txt |
AC |
769 ms |
64728 KiB |
| 38.txt |
AC |
757 ms |
62328 KiB |
| 39.txt |
AC |
133 ms |
9812 KiB |
| 40.txt |
AC |
133 ms |
9808 KiB |
| s1.txt |
AC |
132 ms |
9796 KiB |
| s2.txt |
AC |
132 ms |
9804 KiB |