The 15th UESTC Programming Contest Preliminary G - GC?(X,Y) cdoj1564
地址:http://acm.uestc.edu.cn/#/problem/show/1564
题目:
G - GC?(X,Y)
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 131071/131071KB (Java/Others)
One positive integer can be represented by the product of some prime numbers.
Sort the prime numbers, such like 60=2∗2∗3∗560=2∗2∗3∗5, 180=2∗2∗3∗3∗5180=2∗2∗3∗3∗5.
The GCPGCP(Greatest Common Prefix) of two positive integers is defined as the longest prefix of the multiplication of sorted prime numbers.
For example, GCP(60,180)=Longest_Prefix(2∗2∗3∗5,2∗2∗3∗3∗5)=2∗2∗3=12GCP(60,180)=Longest_Prefix(2∗2∗3∗5,2∗2∗3∗3∗5)=2∗2∗3=12.
Now, for a given array AiAi, calculate
Input
The first line contains a number NN.
The second line contains NN integers AiAi.
1≤N≤105,1≤Ai≤1071≤N≤105,1≤Ai≤107
Output
Output the sum described above.
Sample input and output
Sample Input | Sample Output |
---|---|
5
1 2 8 5 10
|
13
|
Hint
In the sample,
GCP(1,2)=GCP(1,8)=GCP(1,5)=GCP(1,10)=GCP(2,5)=GCP(8,5)=GCP(5,10)=1GCP(1,2)=GCP(1,8)=GCP(1,5)=GCP(1,10)=GCP(2,5)=GCP(8,5)=GCP(5,10)=1,
GCP(2,8)=GCP(2,10)=GCP(8,10)=2GCP(2,8)=GCP(2,10)=GCP(8,10)=2.
时间复杂度:O(nlogn+25nlogn)
3.哈希前缀
1 #include <bits/stdc++.h>
2 using namespace std;
3 #define PB push_back
4 typedef long long LL;
5 const int K=1e5+7;
6 const int maxn=1e7+7;
7 vector<int>num[K],va;
8 vector<LL>vb;
9 int n,pri[maxn],v[K],tol,tag[maxn];
10 LL ans;
11 bool cmp(const vector<int> &ta,const vector<int> &tb)
12 {
13 for(int i=0,j=min(ta.size(),tb.size());i<j;i++)
14 if(ta[i]!=tb[i]) return ta[i]<tb[i];
15 return ta.size()<tb.size();
16 }
17 void init(void)
18 {
19 for (int i = 2; i * i < maxn; i++)
20 {
21 if (tag[i]) continue;
22 for (int j = i; j * j < maxn; j++)
23 tag[i*j] = 1;
24 }
25 for (int i = 2; i < maxn; i++)
26 if (!tag[i])
27 pri[tol++] = i;
28 for(int i=0; i<n; i++)
29 {
30 int t=v[i];
31 num[i].PB(1);
32 for(int j=0; pri[j]*pri[j]<=t; j++)
33 {
34 if(v[i]%pri[j]) continue;
35 while(v[i]%pri[j]==0) v[i]/=pri[j],num[i].PB(pri[j]);
36 }
37 if(v[i]>1) num[i].PB(v[i]);
38 }
39 }
40 void bs(int x)
41 {
42 int sum=1;
43 int l,r,mid,tmp=n-1;
44 va.clear(),vb.clear();
45 for(int i=0;i<num[x].size();i++)
46 {
47 l=x,r=tmp;
48 while(l<=r)
49 {
50 mid=(l+r)/2;
51 if(num[mid].size()>i&&num[mid][i]==num[x][i])
52 tmp=mid,l=mid+1;
53 else
54 r=mid-1;
55 }
56 sum*=num[x][i];
57 va.PB(tmp),vb.PB(sum);
58 }
59 for(int i=num[x].size()-1,ls=x;i>=0;i--)
60 ans+=vb[i]*(va[i]-ls),ls=va[i];
61 }
62 int main(void)
63 {
64 scanf("%d",&n);
65 for(int i=0;i<n;i++)
66 scanf("%d",v+i);
67 init();
68 sort(num,num+n,cmp);
69 for(int i=0;i<n;i++)
70 bs(i);
71 cout<<ans<<endl;
72 return 0;
73 }
动态分配内存的trie树,未ac,mle16了,不想改成左儿子右兄弟了:
1 #include <bits/stdc++.h>
2
3 using namespace std;
4
5 #define MP make_pair
6 #define PB push_back
7 #define MAXNUM 27500
8 typedef long long LL;
9 typedef pair<int,int> PII;
10 const double eps=1e-8;
11 const double pi=acos(-1.0);
12 const int K=1e5+7;
13 const int mod=1e9+7;
14 const int maxn=1e7+7;
15
16
17 vector<int>num[K];
18 map<int,int>hs;
19 int n,pri[maxn],v[K],tol,tag[maxn];
20 int ths[K];
21 LL ans;
22 void make_prime()
23 {
24 for (int i = 2; i * i < maxn; i++)
25 {
26 if (tag[i])
27 continue;
28 for (int j = i; j * j < maxn; j++)
29 tag[i*j] = 1;
30 }
31 for (int i = 2; i < maxn; i++)
32 if (!tag[i])
33 pri[tol++] = i;
34 }
35 void init()
36 {
37 for(int i=0; i<n; i++)
38 {
39 int t=v[i];
40 num[i].PB(1);
41 for(int j=0; pri[j]*pri[j]<=t; j++)
42 {
43 if(v[i]%pri[j]) continue;
44 while(v[i]%pri[j]==0) v[i]/=pri[j],num[i].PB(pri[j]);
45 }
46 if(v[i]>1) num[i].push_back(v[i]);
47 }
48 }
49 typedef struct Trie
50 {
51 int sum,ed;
52 Trie *next[MAXNUM];
53 }Trie;
54 Trie *root;
55 void TrieInit(int sz)
56 {
57 root = (Trie *)malloc(sizeof(Trie));
58 root->sum=root->ed=0;
59 for(int i=0;i<sz;i++)
60 root->next[i]=NULL;
61 for(int j=0;j<n;j++)
62 {
63 Trie *tem=root;
64 for(int i=0;i<num[j].size();i++)
65 {
66 //printf("x=%d:%d %d\n",j,num[j][i],hs[num[j][i]]);
67 if(tem->next[hs[num[j][i]]]==NULL)
68 {
69 Trie *cur = (Trie *)malloc(sizeof(Trie));
70 for(int k=0;k<sz;k++)
71 cur->next[k]=NULL;
72 cur->sum=cur->ed=0;
73 tem->next[hs[num[j][i]]]=cur;
74 }
75 tem = tem->next[hs[num[j][i]]];
76 tem->ed++;
77 }
78 tem->sum++;
79 }
80 }
81 void dfs(Trie *x,LL y,int sz)
82 {
83 Trie *tem = x,*cur;
84 LL ta=0,tb=0,ff=0;
85 if(tem->ed-tem->sum>0)
86 for(int i=0;i<sz;i++)
87 if(tem->next[i]!=NULL)
88 {
89 cur=tem->next[i],ff++;
90 tb+=ta*cur->ed;
91 ta+=cur->ed;
92 if(cur->ed)dfs(cur,y*ths[i],sz);
93 }
94 if(ff>1||tem->sum>0)
95 ans+=y*tb+y*tem->sum*(tem->ed-tem->sum)+y*tem->sum*(tem->sum-1)/2LL;
96
97 }
98
99 int main(void)
100 {
101 int cnt=0;
102 scanf("%d",&n);
103 make_prime();
104 for(int i=0;i<n;i++)
105 scanf("%d",v+i);
106 init();
107 for(int i=0;i<n;i++)
108 {
109 //printf("x=%d: ",i);
110 for(int j=0;j<num[i].size();j++,cnt++)
111 //printf("%d ",num[i][j]),
112 ths[cnt]=num[i][j];
113 //printf("\n");
114 }
115 sort(ths,ths+cnt);
116 int sz=unique(ths,ths+cnt)-ths;
117 for(int i=0;i<sz;i++)
118 hs[ths[i]]=i;
119 TrieInit(sz);
120 for(int i=0;i<sz;i++)
121 if(root->next[i]!=NULL)
122 dfs(root->next[i],ths[i],sz);
123 cout<<ans<<endl;
124 return 0;
125 }
作者:weeping
出处:www.cnblogs.com/weeping/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。