2016 Multi-University Training Contest 1 D HDU 5762 GCD
Posted xtuteam222
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2016 Multi-University Training Contest 1 D HDU 5762 GCD相关的知识,希望对你有一定的参考价值。
题意:给你n个数,然后m个询问,每个询问两个数字l,r,输出x,y,
x=gcd(al,,al+1,...,ar),y表示有多少组l,r使得gcd(al,,al+1,...,ar)=x
思路:x很容易求,直接用线段树即可,求y需要预处理一下,n个数求得的gcd的种类数最多是log2n个,可以用map存一下r=i(a[i])与l前面l<=i(a[i])可以得到的gcd种类及其个数(r是固定的,l<=r);
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll a[500000+10]; 5 char str[10]; 6 struct node 7 { 8 int l,r; 9 ll sum; 10 }tree[4*500000+10]; 11 map<ll,ll>mp1,mp2,cnt;//a[i-1]的gcd种类及个数,a[i]的gcd种类及个数,gcd为i的l,r对数 12 map<ll,ll>::iterator it; 13 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} 14 void build(int l,int r,int node) 15 { 16 tree[node].l=l,tree[node].r=r; 17 if(l==r) 18 { 19 tree[node].sum=a[l]; 20 return ; 21 } 22 int mid=(l+r)>>1; 23 build(l,mid,node<<1); 24 build(mid+1,r,node<<1|1); 25 tree[node].sum=gcd(tree[node<<1].sum,tree[node<<1|1].sum); 26 // printf("%d %lld\n",node,tree[node].sum); 27 } 28 ll cal(int l,int r,int node) 29 { 30 if(l==tree[node].l&&r==tree[node].r) 31 { 32 return tree[node].sum; 33 } 34 int mid=(tree[node].l+tree[node].r)>>1; 35 if(r<=mid)//当前寻找的区间在当前区间左边 36 { 37 return cal(l,r,node<<1); 38 } 39 else if(l>mid)//当前寻找的区间在当前区间右边 40 return cal(l,r,node<<1|1); 41 ll x,y; 42 x=cal(l,mid,node<<1); 43 y=cal(mid+1,r,node<<1|1); 44 return gcd(x,y);//当前寻找的区间在当前区间中间,则将寻找的区间拆分 45 } 46 int main() 47 { 48 int t; 49 scanf("%d",&t); 50 for(int kase=1;kase<=t;kase++) 51 { 52 printf("Case #%d:\n",kase); 53 int n; 54 scanf("%d",&n); 55 for(int i=1;i<=n;i++) 56 { 57 scanf("%lld",&a[i]); 58 } 59 cnt.clear(),mp2.clear(),mp1.clear(); 60 for(int i=1;i<=n;i++) 61 { 62 cnt[a[i]]++; 63 mp2[a[i]]++; 64 for(it=mp1.begin();it!=mp1.end();it++) 65 { 66 ll k=__gcd(a[i],it->first); 67 cnt[k]+=it->second; 68 mp2[k]+=it->second; 69 } 70 mp1.clear(); 71 for(it=mp2.begin();it!=mp2.end();it++) 72 { 73 mp1[it->first]=it->second; 74 } 75 mp2.clear(); 76 } 77 build(1,n,1); 78 int m; 79 scanf("%d",&m); 80 while(m--) 81 { 82 int x,y,xx; 83 xx=min(x,y); 84 y=max(x,y); 85 x=xx; 86 scanf("%d %d",&x,&y); 87 printf("%lld %lld\n",cal(x,y,1),cnt[cal(x,y,1)]); 88 } 89 90 } 91 return 0; 92 }
以上是关于2016 Multi-University Training Contest 1 D HDU 5762 GCD的主要内容,如果未能解决你的问题,请参考以下文章
2016 Multi-University Training Contest 2题解报告
2016 Multi-University Training Contest 1 D HDU 5762 GCD
2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(递推+单线约瑟夫问题)
2016 Multi-University Training Contest 10 [HDU 5861] Road (线段树:区间覆盖+单点最大小)