zoukankan      html  css  js  c++  java
  • P5502 [JSOI2015]最大公约数 题解

    CSDN同步

    原题链接

    简要题意:

    • 给定一个长度为 (n) 的序列 (a),求出其中一个子串 (S),使得 (|S| imes gcd(x in S )). 求这个最大值。
    • 给定一个长度为 (n) 的序列 (a),求出一个区间 ([l,r]) 使得 ((r-l+1) imes gcd_{i=l}^r a_i) 最大.求这个最大值。

    (n leq 10^5 , 1 leq a_i leq 10^{12}).

    两种不同表达的题意而已。

    首先,抛出一个非常有用的结论:

    • 最大值对应的区间长度不超过 (log n).

    为什么呢?

    固定右区间 (r) ,枚举 (l) 向左拓展,每拓展一次,(gcd) 要么不变,要么 (leq) 原来 (gcd) 的一半。 这样,不同的 (gcd) 的值最多只有 (log n) 个.

    这样我们给定 (r) 用类似单调队列的方法维护即可。

    时间复杂度:(mathcal{O}(n log n log a_i)).

    实际得分:(100pts).

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int N=1e6+1;
    #define L (x<<1)
    #define R (x<<1)+1
    
    inline ll read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
    	ll x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
    
    inline void write(ll x) {
    	if(x<0) {putchar('-');write(-x);return;}
    	if(x<10) {putchar(char(x%10+'0'));return;}
    	write(x/10);putchar(char(x%10+'0'));
    }
    
    int n;
    queue<int> q,qq;
    ll a[N],ans=0;
    
    inline ll gcd(ll n,ll m) {return !m?n:gcd(m,n%m);} //计算 gcd
    signed main() {
    	n=read(); a[0]=-1;
    	for(int i=1;i<=n;i++) {
    		a[i]=read(); int l=0;
    		while(!q.empty()) {
    			int x=q.front(); q.pop(); //printf("%d
    ",x);
    			a[x]=gcd(a[x],a[i]);
    			ans=max(ans,a[x]*(i-x+1)); //更新答案
    			if(a[x] == a[l]) continue;
    			qq.push(x); l=x; //新的决策点
    		} ans=max(ans,a[i]);
    		while(!qq.empty()) {
    			q.push(qq.front()); qq.pop();
    		} if(a[l] != a[i]) q.push(i);
    	} write(ans);
    	return 0;
    }
    
    
    
  • 相关阅读:
    elasticsearch 基本操作
    ElasticSearch停止启动
    oracle误删数据
    多层级sql查询
    max_result_window
    测试ik分词效果
    TransportClient 新建index,mappings dynamic_templates。
    7.10考试
    C#生成TXT文件
    C#的进度条--progressBar
  • 原文地址:https://www.cnblogs.com/bifanwen/p/13380278.html
Copyright © 2011-2022 走看看