ECNU Online Judge P3733 alphabet game

Original title link: https: //acm.ecnu.edu.cn/problem/3733/

 

Preface: In fact, in retrospect, if time can hash this thing, it is estimated to do it, and then into the top 20 (laughing cry), tcl. Tonight tune one night and found everywhere changed after the hash bugQWQ

 

analysis:

Can be found due to the equivalence transferable, in the case where K> = 7 would be completely without special treatment, the answer is C (N, 2), because this time all the words are equivalent, then all strings are the equivalent.

For the case of K <= 7, it was found that in fact we limit according to the subject K is eight characters divided into several sets, the equivalent letter within the set. According to the second Stirling number (the back will make up a related article), you can find a meaningful total number of states (that is, all of the K equivalent conditions of use, and equivalent conditions of use does not form a ring) probably less than 5,000, then you can consider enumerate each division.

Enumeration about division, considered an equivalent condition, in fact, can be seen as a side, we have to meaningful use of all sides, it is to generate a tree (or forest). Spanning Forest father, then as long as the enumeration of each point in a recursive process, and to ensure that the father character corresponds to less than the current character.

After completion of partitioning, consider the comparison string. Violence will contrast T, consider the hash, and optimization. Pretreatment time for a string, the string that is i, the hash value is split wherein different character count of open, i is obtained by addition of a character into a character corresponding to the hash value of a string of i contribution. Dividing each time after the last string generated just by comparing O (8) The pretreatment time the contents can be combined to give the correct hash value corresponds.

After calculating the time complexity of each division is completed O (nlogn), by this question.

 

(Do not very long title, after the title tune for a long time thinking out the details, the root of the problem for the unified character looking tree and initially did not realize)

 

AC Code:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<set>
 9 #include<map>
10 #include<vector>
11 #include<cctype>
12 using namespace std;
13 typedef long long LL;
14 const LL mo=1e15+13;
15 const int maxn=1005 ;
 16  
. 17  char S [MAXN] [MAXN]; int N, M, K, ANS;
 18 is  int FA [ 10 ], RT [ 10 ];
 . 19 LL the Hash [MAXN] [ 10 ] [ 10 ], Val [MAXN ]; // hash [i] [j] [k] denotes the i-th character string converted into the corresponding hash value j k character of 
20 is  
21 is  void the data_in ()
 22 is  {
 23 is      Scanf ( " % D% D% D " , N &, & M, & K);
 24      for ( int I = . 1 ; I <= N; I ++ )
 25          Scanf ( "%s",S[i]);
26 }
27 void ready()
28 {
29     for(int i=1;i<=N;i++)
30     for(int k=0;k<8;k++){
31         LL tmp=1;
32         for(int j=0;j<M;j++){
33             int jj=S[i][j]-'a';
34             Hash[i][jj][k]=(Hash[i][jj][k]+tmp*k)%mo;
35             tmp=tmp*29%mo;
36         }
37     }
38 }
39 LL Hash_val(int i)
40 {
41     LL re=0;
42     for(int j=0;j<8;j++)
43         re+=Hash[i][j][rt[j]];
44     return re%mo;
45 }
46 int root(int j)
47 {
48     while(fa[j]!=j) j=fa[j];
49     return j;
50 }
51 void calc()
52 {
53     for(int j=0;j<8;j++) rt[j]=root(j);
54     for(int i=1;i<=N;i++)
55         val[i]=Hash_val(i);
56     sort(val+1,val+N+1);
57     int i=1,re=0;
58     while(i<=N){
59         int cnt=1;
60         while(i<N&&val[i]==val[i+1]) i++,cnt++;
61         re+=cnt*(cnt-1)/2;
62         i++;
63     }
64     if(re>ans) ans=re;
65 }
66 void run(int i,int k)
67 {
68     if(i==8&&k==K){ calc(); return; }
69     if(i==8||k>K) return;
70     fa[i]=i;
71     run(i+1,k);
72     for(int j=0;j<i;j++){
73         fa[i]=j;
74         run(i+1,k+1);
75     }
76 }
77 void work()
78 {
79     fa[0]=0;
80     if(K>=7) ans=N*(N-1)/2;
81     else{
82         ready();
83         run(1,0);
84     }
85     printf("%d\n",ans);
86 }
87 int main()
88 {
89     freopen("test.in","r",stdin);
90     freopen("test.out","w",stdout);
91     data_in();
92     work();
93      Return  0 ;
94 }
View Code

 

Guess you like

Origin www.cnblogs.com/Golden-Elf/p/11986053.html
Recommended