bzoj 4488: [Jsoi2015]最大公约数
生活随笔
收集整理的這篇文章主要介紹了
bzoj 4488: [Jsoi2015]最大公约数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
4488: [Jsoi2015]最大公約數
Time Limit: 10 Sec??Memory Limit: 256 MBSubmit: 270??Solved: 154
[Submit][Status][Discuss]
Description
給定一個長度為 N 的正整數序列Ai對于其任意一個連續的子序列
{Al,Al+1...Ar},我們定義其權值W(L,R )為其長度與序列中所有元素的最大公約數的乘積,即W(L,R) = (R-L+1) ? gcd (Al..Ar)。
JYY 希望找出權值最大的子序列。
Input
輸入一行包含一個正整數 N。
接下來一行,包含 N個正整數,表示序列Ai
1 < =? Ai < =? 10^12, 1 < =? N < =? 100,000
Output
輸出文件包含一行一個正整數,表示權值最大的子序列的權值。
Sample Input
530 60 20 20 20
Sample Output
80//最佳子序列為最后 4 個元素組成的子序列。
HINT
Source
[Submit][Status][Discuss]
題解:若n個元素,其后綴所有不同的gcd,不會超過log(n)個,因此可以枚舉右端點,進行暴力更新,我們可以設st[2][NMAX],in[2][NMAX]數組,
st數組存取后綴gcd,in數組存取第一次出現gcd的位置,st和in中的2表示有兩個狀態(即以上一個點為后綴和當前點為后綴),每次都用上一個點
的信息更新當前點的信息。
c++ code:
#include <iostream> #include <cstdio> #include <set> #include <map> #include <algorithm>using namespace std; const int NMAX=1e5+7; typedef long long ll; ll st[2][NMAX],in[2][NMAX],p,top[2],a[NMAX]; map<ll,int>my;ll gcd(ll a,ll b) {return b?gcd(b,a%b):a; } void init() {top[0]=top[1]=p=0; } int main() {int n;init();scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld",&a[i]);st[p][top[p]]=a[1];in[p][top[p]++]=1;ll ans=a[1];for(int i=2;i<=n;i++){my.clear();for(int j=0;j<top[p];j++){ll GCD=gcd(st[p][j],a[i]);ans=max(ans,GCD*(i-in[p][j]+1));if(!my[GCD]){st[!p][top[!p]]=GCD;in[!p][top[!p]++]=in[p][j];my[GCD]++;}}ans=max(ans,a[i]);if(!my[a[i]]){st[!p][top[!p]]=a[i];in[!p][top[!p]++]=i;my[a[i]]++;}top[p]=0;p=!p;}printf("%lld\n",ans);return 0; }?
轉載于:https://www.cnblogs.com/lemon-jade/p/8604214.html
總結
以上是生活随笔為你收集整理的bzoj 4488: [Jsoi2015]最大公约数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7、linux网络编程--广播
- 下一篇: 服务端2