当前位置: 首页>Php>正文

調和級數時間復雜度,51nod 1421 最大MOD值(高妙的調和級數復雜度)

調和級數時間復雜度,51nod 1421 最大MOD值(高妙的調和級數復雜度)

有一個a數組,里面有n個整數。現在要從中找到兩個數字(可以是同一個)?ai,aj?,使得?ai?mod?aj?最大并且?ai??aj

Input
單組測試數據。
第一行包含一個整數n,表示數組a的大小。(1?≤?n?≤?2*10^5)
第二行有n個用空格分開的整數ai?(1?≤?ai?≤?10^6)。
Output
輸出一個整數代表最大的mod值。
Input示例
3
3?4?5
Output示例
2

題解:首先考慮mod的真正定義
a%b=a/b*b+c
思考一下其實是kb+c的形式,畫在數軸上就是

很顯然,如果有一個數x%a>b%a他肯定會在(k*a+b,(k+1)*a)的區間之中,到底有沒有這些數存在可以用前綴和O(1)查詢

所以因此我們就可以對c即余數進行二分了,不過二分的時候檢驗是O(nlogn)的,因為會枚舉每一個數的倍數的區間,總復雜度大約是調和級數即logn 但其實仔細一想這是不滿的

在套上二分,復雜度是O(nlognlogn)?

調和級數時間復雜度、代碼如下:

#pragma GCC optimize("inline",3)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;int vis[4000010],sum[4000010],k,n,a[200010],cnt;int check(int x)
{for(register int i=1;i<=cnt;++i){for(register int j=a[i];j<=1e6;j+=a[i]){if(sum[j+a[i]-1]-sum[j+x-1]>0){return 1;}}}return 0;
}int main()
{scanf("%d",&n);int tmp;for(register int i=1;i<=n;++i){scanf("%d",&tmp);if(!vis[tmp]){vis[tmp]=1;}}for(register int i=1;i<=2e6;++i){sum[i]=sum[i-1]+vis[i];}for(int i=1;i<=1e6;i++){if(vis[i]){a[++cnt]=i;}}register int l=0,r=2e6,mid;while(l<r){int mid=(l+r)>>1;if(check(mid)){l=mid;}else{r=mid-1;}if(r-l<=1){r=check(r)?r:l;break;}}printf("%d\n",r);
}

這個程序1e5跑跑是非常輕松的但是到了2e5就有點力不從心了

直接提交到51nod上就大概只能過18個點

于是考慮優化,其實只要知道了上面那個mod的定義,我們每次對于(k+1)*ai找到小于它的最大aj,那么這個aj%ai的值肯定是(k*ai,(k+1)*ai)區間內所有數%ai最大的

因此我們可以先預處理出f[i]為比i小的最大ai,然后在向上面一樣枚舉區間對于每個區間計算最大模數更新答案,因為省去了二分,復雜度就是O(nlogn)

代碼如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;int b[2000010],a[200010],n,t,ans=-1;int cmp(int a,int b)
{return a>b;
}int main()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}sort(a+1,a+n+1,cmp);int t=unique(a+1,a+n+1)-a-1;n=t;int j=1;for(int i=2e6;i>=1;i--){while(j<=n&&a[j]>=i) j++;b[i]=a[j];}    for(int i=1;i<=n;i++){for(int j=2;j<=2e6/a[i];j++){ans=max(ans,b[a[i]*j]%a[i]);}}printf("%d\n",ans);
}

求解最大非空子數組的時間復雜度,?

?

yzy大佬用set隨手A掉了此題
詳見這里
https://blog.csdn.net/yzyyylx/article/details/81013038

轉載于:https://www.cnblogs.com/stxy-ferryman/p/9299081.html

https://www.nshth.com/php/338378.html
>

相关文章:

  • 調和級數時間復雜度
  • 求解最大非空子數組的時間復雜度
  • mod112
  • 數據集合為D1
  • 3
  • 5
  • 7
  • 9
  • 語言使用排行榜,PHP2020語言排行榜,TIOBE公布了2020年12月編程語言排行榜
  • 你好,爬取《你好,李煥英》影評,并生成詞云圖
  • php手冊中文版,PHP筆記 17 18 19 20 21
  • ubuntu怎么切換中文輸入法,ubuntu系統配置中文輸入法以及安裝ros2,docker等開發環境
  • qt設置控件在布局的位置,Qt自定義控件(IP輸入框,windows下)
  • 計算機初級考試內容自測題,計算機基礎知識考題及答案,計算機基礎知識試題及答案(一)
  • 商標查詢,龍門標局:R商標是指什么?購買的商標能標注R嗎?
  • 蘇州注冊公司流程和步驟,蘇州企業拿到商標注冊證后,需要注意哪些事項?
  • 注冊一個商標要多久可以批下來,2022年商標注冊需要多長時間?
  • testflight教程,【技術分享】TestFlight測試的流程文檔
  • ios開發者測試版,iOS APP真機測試及上架App Store流程記錄
  • iphone怎么安裝證書,Windows申請iOS證書上架App Store詳細教程 (有這一篇就夠了)
  • 銀河證券章俊,章俊
  • 央行定向降準是什么意思,央行工作會議說了什么:定向調控 松緊適度
  • 機械制造及其自動化畢業設計,計算機在機械設制造中的應用實例,機械設計與制造畢業設計一體化分析
  • 問句和疑問句的區別,問句識別:基于Xgboost的中文疑問句判斷模型
  • 多線程sleep和wait的區別,非wait線程即時喚醒epoll_wait
  • 服務器終端,服務器TIME_WAIT和CLOSE_WAIT區別及解決方案
  • linux查看最大連接數,linux表示文件連接數,linux中連接數過多(TIME_WAIT/CLOSE_WAIT)讀這一篇就夠了
  • 視頻渲染用什么顯卡,Android視頻解碼及渲染
  • 百家號視頻怎么算原創,百家號基于AE的視頻渲染技術探索
  • 視頻制作,常見幾種視頻渲染模式介紹
  • 電子商務運營技能大賽,2022年ITMC暢享杯全國職業院校電子商務技能大賽SEM直通車競賽平臺介紹思路打法
  • Android基礎入門教程,花2萬塊買的教程!Android技術功底不夠如何去面試,大廠直通車!
  • 拼多多直通車出價技巧,直通車拼多多7天均價比價
  • flutter開發小程序,寫給程序員的Flutter詳細教程,大廠直通車!
  • 聚合支付是什么東西,聚合支付行業術語,你get到了嗎?
  • 支付行業發展現狀及趨勢,支付行業的一些名詞
  • 調和級數時間復雜度,51nod 1421 最大MOD值(高妙的調和級數復雜度)
  • mysql數據庫臟讀解決方案,數據庫事務臟讀、幻讀、不可重復讀的解決方法