地址: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 #include2 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 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; ivb; 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 ) ) 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 ) 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 ) 66 scanf("%d",v+i); 67 init(); 68 sort(num,num+n,cmp); 69 for(int i=0;i ) 70 bs(i); 71 cout< endl; 72 return 0; 73 }
动态分配内存的trie树,未ac,mle16了,不想改成左儿子右兄弟了:
1 #include2 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 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) ) 60 root->next[i]=NULL; 61 for(int j=0;j ) 62 { 63 Trie *tem=root; 64 for(int i=0;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 ) 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 ) 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 ) 105 scanf("%d",v+i); 106 init(); 107 for(int i=0;i ) 108 { 109 //printf("x=%d: ",i); 110 for(int j=0;j ) 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 ) 118 hs[ths[i]]=i; 119 TrieInit(sz); 120 for(int i=0;i ) 121 if(root->next[i]!=NULL) 122 dfs(root->next[i],ths[i],sz); 123 cout< endl; 124 return 0; 125 }