• UVA 1642 MagicalGCD 题解


    题面

    本题是一道区间最大公约数的模板题;

    如果N^2暴力的话当然会超时,所以我们要发掘出区间gcd的特点;

    设gcd[i]表示区间[1,i]的最大公约数;

    我们可以发现,从一个点i到1之间的所有区间的gcd均满足gcd[j]=GCD(gcd[j-1],a[j]);

    由于gcd的性质,所以gcd[]是单调不增的;

    接着,我们似乎发现了一个更神奇的事情,g[]中不同的值最多有log(max(a[i]))个;

    换句话说,虽然g[]数组的长度为n,但在以上两个条件的限制下,最多仅仅有logA个值发生改变的地方;

    所以我们遍历一遍右端点,处理出每个i到j(0<=i<=j)的区间的最大公约数;

    注意,这并不再是n^2了,因为从i到j在long long 范围内最多有64个不同的值,所以我们只要遍历一遍这些点i就可以知道所有的0<=i<=j到j的区间的gcd;

    神奇吧?

    综上所述,求出所有区间的gcd仅仅需要nlogA的时间,完全可以切掉这道题;

    #include <bits/stdc++.h>
    #pragma GCC optimize(3)
    #define ll long long
    using namespace std;
    int n;
    long long a[100010];
    long long gcd(long long a,long long b)
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    vector<pair<long long ,long long> > vec[100010]; //第一维是值,第二维是在枚举右端点所用的点的编号
    int main ()
    {
        cin>>n;
        for(register int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(register int i=1;i<=n;i++){
            long long x=a[i],y=i;        
            vec[i].push_back(make_pair(x,y));        
            for(register int j=0;j<vec[i-1].size();j++){
                if(x==1) break;
                long long GCD=gcd(x,vec[i-1][j].first);    
                if(GCD!=x){
                    x=GCD;
                    y=vec[i-1][j].second;
                    vec[i].push_back(make_pair(x,y));
                }
            }
        }
        long long ans=0;
        for(register int i=1;i<=n;i++){
            int w=vec[i].size()-1;
            for(register int j=0;j<w;j++){
                pair<long long,long long> p1=vec[i][j];
                pair<long long,long long> p2=vec[i][j+1];
                ans=max(ans,p1.first*(i-p2.second)); //注意,i-p2.second却不加1的原因是因为该区间其实是[p2.second,i-1];
            }
            ans=max(ans,vec[i][vec[i].size()-1].first*i);
        }
        cout<<ans;
    }
  • 相关阅读:
    Centeos7搭建selenium+Chrome浏览器
    数据结构学习篇之栈和队列
    数据结构学习篇之线性表
    Tornado基础学习篇
    Python控制函数运行时间
    python线程实现异步任务
    Python实现几种简单的排序算法
    python爬虫遇到会话存储sessionStorage
    Python 有哪些优雅的代码实现让自己的代码更pythonic?
    Ubuntu查看端口使用情况,使用netstat命令:
  • 原文地址:https://www.cnblogs.com/kamimxr/p/11295135.html
Copyright © 2020-2023  润新知