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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【二分】走亲戚

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【二分】走亲戚 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意

平面上有n個點,給出m個詢問,每個詢問要回答從x輪流往右往左去到最遠的點,最后到達的點


解題思路

對于每個詢問,每次二分左右可以到多遠,直到不能動為止

考慮時間,對于重復走一個范圍的,可以直接模掉

對于范圍縮小的(如下圖),如果走了黑的的一段,則下一段的長度不會大于紅色的一段(上面是因為如果大于則可以走完一程,下面的是因為范圍最大為紅色),所以每一次走的距離會小于上一次的一半

所以時間復雜度為O(mlognlog109)O(m\ logn\ log10^9)O(m?logn?log109)

code

#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 200021 #define mp make_pair #define fs first #define sn second using namespace std; ll n,m,x,k,l,r,L,R,mid,len,v[N],a[N]; pair<ll,ll>b[N]; int main() {scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;++i){scanf("%lld",&x);b[i]=mp(x,i);}sort(b+1,b+1+n);for(ll i=1;i<=n;++i)v[b[i].sn]=i,a[i]=b[i].fs;len=(a[n]-a[1])*2;if(n==1){while(m--)puts("1");return 0;}while(m--){scanf("%lld%lld",&x,&k);x=v[x];k%=len;l=x;r=n;while(l<r){//先走到最后面mid=l+r+1>>1;if(k<a[mid]-a[x])r=mid-1;else l=mid;}L=1;R=l;k-=a[l]-a[x];while(L<R){k%=(a[R]-a[L])*2;l=L;r=R;while(l<r){//來回走mid=l+r>>1;if(k<a[R]-a[mid])l=mid+1;else r=mid;}L=l;k-=a[R]-a[l];l=L;r=R;while(l<r){mid=l+r+1>>1;if(k<a[mid]-a[L])r=mid-1;else l=mid;}R=l;k-=a[l]-a[L];}printf("%lld\n",b[L].sn);}return 0; }

總結

以上是生活随笔為你收集整理的【二分】走亲戚的全部內容,希望文章能夠幫你解決所遇到的問題。

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