日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二分(三分)+快速幂

發布時間:2023/11/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二分(三分)+快速幂 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前學習的二分,現在感覺突然理解許多,補一下總結
首先,二分能夠解決什么樣的問題呢,個人認為,二分能夠快速解決已經知道答案范圍(線性)但是不知道確切答案的問題,例如在一個有序序列中查找某一元素出現的(最早,最晚)位置,求某單調(或在給定區間上單調)函數的零點,最大化最小值或者最小化最大值等等
二分的模板大體如下:

int l=x;//x表示元素可能出現的最小(最左邊)的情況 int r=y;//y表示元素可能出現的最大(最右邊)的情況 int ans,mid; while(i<=l) {mid=(l+r)/2; //二分if(check(mid))//判斷中點的情況{l=mid+1;ans=mid; //或者ans=max(ans,mid)等,ans用于保存答案,如果需要所有可行答案中的最大值或者最小值加上max或者min即可}else{r=mid-1;} }

總體來講二分的思想還是比較簡單的,但是問題的難點經常不是考慮不到二分,而是考慮到二分卻不知道如何判斷要查找的元素在mid的情況下能否可行,即如何編寫check(mid)函數。這個函數的編寫往往要仔細考慮要查找元素的特征(以及腦洞)。
比如經常出現的最大化最小值和最小化最大值等,那些放牛的等問題判斷起來還是比較容易的,就從開始一個一個按照條件放,如果能行就能行。但是更多的問題還是比較靈活的,比如POJ - 3104

題意大概是一個人冬天洗衣服想要讓衣服盡快的干問最少需要多少時間。
這個我們很容易確定所花最長時間是水分最多的衣服所含有的水分(不用那個烘干器自然風干),最短時間為0,但是給定一個時間,我們怎么判斷這個時間內可不可以將衣服晾干呢?
這就需要我們進行一個轉換,我們不妨這樣想:這些衣服先晾了mid分鐘,然后再將還沒有干的全部用烘干器烘干,烘干器只能烘mid次,每次烘干k-1的水分。
乍看好像有些無厘頭,其實仔細一想很簡單,我們只不過把原來一起做的事情拆開來分析而已(表示不好想到)。
這樣的話我們遍歷每件衣服,如果它沒有自己晾干就得用烘干器,如果在mid次以內全部烘干了就可以,如果沒有就不行。
需要注意一點的是如果原本烘干器是個假的烘干器(每分鐘烘干的速度和晾衣服的速度一樣),那么只處理晾后的,就不要用烘干器再處理了(烘干器每次處理0,不注意這點的話可能會re,我re了好多次才注意到)。

附AC代碼:

#include<cstdio> #include<cstring> #include<algorithm> using namespace std;int n,k; int a[100100];bool cmp(int a,int b) {return a>b; } bool check(int time) {int tmp=time;int t;for(int i=0;i<n;i++){t=a[i]-time;if(t>0){if(k==0)return false;tmp-=t/k;if(t%k!=0)tmp--;}if(tmp<0)return false;}return true; } int main() {int tmp;memset(a,0,sizeof(a));scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);}scanf("%d",&k);k--;sort(a,a+n,cmp);int l=0,r=a[0];int ans=0,mid;while(l<=r){mid=(l+r)/2;if(check(mid)){r=mid-1;ans=mid;}else{l=mid+1;}}printf("%d",ans);return 0; }

除此之外二分法快速冪也經常使用,必須熟記(雖然我覺得是一個遞歸)
快速冪板子(非遞歸寫法):

long long qucik_pow(long long a,long long n,long long m)//求a^n%m {long long ans=1;while(n){if(n&1) ans=(ans*a)%m;a=a*a%m;n>>=1;}return ans%m; }

還有遞歸寫法(有助于理解快速冪,但是不常用)

long long quick_pow(long long a,long long n,long long m) {if(n==1) return a;if(n%2==0){long long t=quick_pow(a,n/2,m);return t*t%m;}else{long long t=quick_pow(a,b/2,m);t=t*t%m;t=t*a%m;return t;} }

三分的話每太用過,只是見過用來求凸凹函數的極值點
思想就是先將區間二分,在將其中一個區間二分,然后比較兩個點的大小,哪個距離極值點遠就將哪一邊更新,應該是可以根據凹凸函數的性質進行證明的(我比較懶就不證明了,有時間再證吧),附一下板子:

while(left+eps<right) {midl=(left+right)/2;midr=(midl+right)/2;if(f(midl)<f(midr)){right=midr;}else{left=midl;} }

總結

以上是生活随笔為你收集整理的二分(三分)+快速幂的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。