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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

CF1019D-Large Triangle【计算几何,二分】

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

正題

題目鏈接:https://www.luogu.com.cn/problem/CF1019D


題目大意

給出nnn個點,保證沒有三點共線,求是否有三個點圍成的三角形面積恰好為SSS

3≤n≤2×103,1≤S≤2×10183\leq n\leq 2\times 10^3,1\leq S\leq 2\times 10^{18}3n2×103,1S2×1018


解題思路

一個暴力的思想是我們可以去枚舉底邊,然后找頂點。

此時底邊的長度固定,而高度就是頂點離底邊所在直線的距離,而這題問的是需要找面積為SSS的,所以我們可以考慮從近到遠二分。

但是如何得到距離直線從近到遠的序列,因為我們是枚舉的,我們考慮能否從上次的信息得到這次的信息,主要到原來順序中的一對數x,yx,yx,y滿足xxx離的更近當且僅當原來枚舉的線段斜率小于xxxyyy的線段斜率,而同理當枚舉到斜率大于它時xxx就排到yyy后面了。

那么這樣方法就已經很顯然了,我們把所有點對之間的線段按照斜率從小到大排序枚舉,然后處理完x→yx\rightarrow yxy后交換x,yx,yx,y在序列中的順序就好了,這樣每次維護好序列后我們就可以二分做了。

時間復雜度:O(n2log?n2)O(n^2\log n^2)O(n2logn2)


code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2100; struct point{ll x,y,id;point(ll xx=0,ll yy=0){x=xx;y=yy;} }a[N],e[N*N/2]; ll n,s,cnt,rk[N],sa[N]; point operator-(point a,point b) {return point(a.x-b.x,a.y-b.y);} ll operator^(point a,point b) {return a.x*b.y-a.y*b.x;} bool cmp(point x,point y) {return x.x<y.x;} bool cMp(point x,point y) {return ((a[x.y]-a[x.x])^(a[y.y]-a[y.x]))>0;} ll calc(point a,point b,point c) {return abs((b-a)^(c-a));} signed main() {freopen("triangle.in","r",stdin);freopen("triangle.out","w",stdout);scanf("%lld%lld",&n,&s);s=s*2ll;for(ll i=1;i<=n;i++)scanf("%lld%lld",&a[i].x,&a[i].y);sort(a+1,a+1+n,cmp);for(ll i=1;i<=n;i++)for(ll j=1;j<i;j++)e[++cnt]=point(j,i);sort(e+1,e+1+cnt,cMp);for(ll i=1;i<=n;i++)rk[i]=sa[i]=i;for(ll i=1;i<=cnt;i++){ll x=e[i].x,y=e[i].y;ll l=1,r=min(rk[x],rk[y])-1;while(l<=r){ll mid=(l+r)>>1;if(calc(a[x],a[y],a[sa[mid]])<s)r=mid-1;else l=mid+1;}if(r&&calc(a[x],a[y],a[sa[r]])==s){puts("Yes");printf("%lld %lld\n",a[x].x,a[x].y);printf("%lld %lld\n",a[y].x,a[y].y);printf("%lld %lld\n",a[sa[r]].x,a[sa[r]].y);return 0;}swap(rk[x],rk[y]);swap(sa[rk[x]],sa[rk[y]]);}puts("No");return 0; }

總結

以上是生活随笔為你收集整理的CF1019D-Large Triangle【计算几何,二分】的全部內容,希望文章能夠幫你解決所遇到的問題。

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