【NOIP2014模拟8.17】Magical GCD
2016-10-12 20:08
489 查看
Description
对于一个由正整数组成的序列, Magical GCD 是指一个区间的长度乘以该区间内所有数字的最大公约数。给你一个序列,求出这个序列最大的 Magical GCD。Input
单个测试点包含多组数据。输入的第一行是一个整数T表示数据组数。
每组数据的第一行是一个整数N,描述序列长度。
接下来N个数字,描述这个序列元素A[i]。
Output
对于每组测试数据输出一行,包含一个整数,表示序列最大的 Magical GCD。Sample Input
15
30 60 20 20 20
Sample Output
80Data Constraint
对于 30%分值的数据,N <= 10,T <= 11,000, A[i] <= 100对于剩余 70%分值的数据,N <= 100,000,T <= 20, A[i] <= 10^12
C/C++选手读入和输出 64 位整数请使用%lld。
Hint
【样例说明】对于子区间 60 20 20 20,长度为 4,最大公约数为 20,此段 Magical GCD 为 80.
Solution
先考虑暴力,直接枚举两边端点,求GCD,显然只有30分。正解需要从暴力出发
在暴力时,右端点l向右移动一格会有什么改变呢?
设g[i]表示当前右端点为l,i到l的GCD
当l向右移时,g[i]单调不增
而且最多只有log2(n)个点,值也只有log2(a[i])种
那么用链表维护g[i],只要连续g[i]两个相同,就删掉右边的,只保留左边的,保证了单次时间复杂度为O(n∗log2(n))
Code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define N 101000 using namespace std; int n,tot; ll a ,g ; struct node{ int l,r; }; node e ; ll gcd(ll m,ll n) { for(ll r=n;r!=0;r=m%n,m=n,n=r); return m; } int main() { int ac; for(scanf("%d",&ac);ac;ac--) { scanf("%d",&n);tot=0; for(int i=1;i<=n;i++) e[i].r=i+1,e[i].l=i-1,scanf("%lld",&g[i]); ll ans=0; for(int l=1;l<=n;l++) { for(int i=1;i<=l;i=e[i].r) { g[i]=gcd(g[i],g[l]);ans=max(ans,g[i]*(ll)(l-i+1)); if(g[i]==g[e[i].l]) e[e[i].l].r=e[i].r,e[e[i].r].l=e[i].l; } } printf("%lld\n",ans); } }
相关文章推荐
- 【NOIP2014模拟8.17】Magical GCD
- 【NOIP2014模拟8.17】Magical GCD
- jzoj3782 [NOIP2014模拟8.17] 组队
- JZOJ 3782. 【NOIP2014模拟8.17】组队
- 【NOIP2014模拟8.17】Multiset //2018.2.5
- JZOJ3782. 【NOIP2014模拟8.17】组队
- jzoj3782 【NOIP2014模拟8.17】组队 (特殊情况的2sat,dp)
- 【NOIP2014模拟8.17】Magical GCD//2018.2.5
- 【JZOJ 3823】【NOIP2014模拟9.9】遇见
- [jzoj]3729. 【NOIP2014模拟7.10】表达式的值(exp) (分块转化模型)
- 【NOIP2014模拟11.2A组】福慧双修
- JZOJ 3815. 【NOIP2014模拟9.7】克卜勒
- 【jzoj5289】【NOIP2017提高组A组模拟8.17】【偷笑】【数据结构】
- JZOJ 3839【NOIP2014模拟9.14】Baby Step
- JZOJ 4709 Matrix【NOIP2016提高A组模拟8.17】
- 【NOIP2016提高A组模拟8.17】Matrix
- jozj. 3927. 【NOIP2014模拟11.6】可见点数 洛谷 P2158 [SDOI2008]仪仗队
- 3928. 【NOIP2014模拟11.6】射击
- NOIP2014模拟8.21