• 紫书 例题 10-29 UVa 1642(最优连续子序列)


    这类求最优连续子序列的题一般是枚举右端点,然后根据题目要求更新左端点,

    一般是nlogn,右端点枚举是n,左端点是logn

    难点在于如何更新左端点

    用一些例子试一下可以发现

    每次加进一个新元素的时候

    前面的元素都要再取一遍gcd

    然后gcd同的时候i尽量大

    为了去重,我们需要排序,用相邻元素比较

    保留下来最优的一些区间,然后更新答案

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 112345;
    ll a[MAXN];
    
    struct node
    {
    	ll g;
    	int p;
    	bool operator < (const node& rhs) const
    	{
    		return (g < rhs.g) || (g == rhs.g && p < rhs.p);
    	}
    };
    
    ll gcd(ll a, ll b) { return !b ? a : gcd(b, a % b); }
    
    int main()
    {
    	int n, T;
    	scanf("%d", &T);
    	
    	while(T--)
    	{
    		scanf("%d", &n);
    		REP(i, 0, n) scanf("%lld", &a[i]);
    		vector<node> g;
    		ll ans = 0;
    		
    		REP(i, 0, n)
    		{
    			g.push_back(node{0, i});
    			REP(j, 0, g.size())
    				g[j].g = gcd(g[j].g, a[i]);
    			sort(g.begin(), g.end());
    			
    			vector<node> newg;
    			REP(j, 0, g.size())
    				if(j == 0 || g[j].g != g[j-1].g)
    				{
    					newg.push_back(g[j]);
    					ans = max(ans, g[j].g * (i - g[j].p + 1));
    				}
    			g = newg;
    		}
    		
    		printf("%lld
    ", ans);
    	}
     
    	return 0;
    }
  • 相关阅读:
    如何带平均年龄小的团队
    如何带平均年龄大的团队
    Extjs中常用表单介绍与应用
    .NET 应用架构指导 V2[17]
    一个男人的关心的东西
    微软企业库5.0学习笔记(十四)
    .NET 应用架构指导 V2[19]
    微软企业库5.0学习笔记(十五)
    计算机基本图书
    vs添加博客园精华区
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819490.html
Copyright © 2020-2023  润新知