YbtOJ 853 平面標記 整體二分,凸殼

2022-03-29 04:01:37 字數 1566 閱讀 7206

給出\(n\)個點\((x_i,y_i)\),\(m\)次給出\((k_i,a_i)\)表示標記所有滿足

\[y_j>\frac}

\]的未標記點

求每個點的標記時間

\(1\leq n,m\leq 10^5,1

全是乘法所以可以先左右取\(ln\)就是

\[ln(y_j)>ln(k_i)-ln(x_j)\times a_i

\]把\(x,y,k\)取\(ln\)然後就是乙個順眼的式子

\[x_j\times a_i+y_i>k_i

\]雖然原題說\((x_i,y_i)\)是點,但是我們可以換個思路,把\((x_i,y_i)\)看成邊(\(f(z)=x_iz+y_i\)),\((a_i,k_i)\)看成是點,然後問在每條邊下面的編號最小的點是哪個。

這個就很好解決了,考慮整體二分。每次要考慮對於一條邊是否有在\([l,mid]\)編號的點在它下面。可以對於所有的\([l,mid]\)的點拿出來構成乙個下凸殼,然後根據每條邊的斜率二分出乙個最下面的點,然後只拿這個點判斷就好了。

這樣就是\(o(n\log^2 n)\)的了,如果肯寫歸併排序和凸殼用單調佇列維護是可以做到\(o(n\log n)\)的

#include#include#include#includeusing namespace std;

const int n=1e5+10;

int n,m,f[n],s[n],p[n],p1[n],p2[n],top,pos[n];

double x[n],y[n],k[n],z[n];

double xj(double x1,double y1,double x2,double y2)

double xl(int a,int b,int c)

bool cmp(int x,int y)

int mid=(lm+rm)>>1;top=0;

sort(pos+lm,pos+1+mid,cmp);

for(int i=lm;i<=mid;i++)

sort(pos+lm,pos+1+mid);

int cnt1=0,cnt2=0;

for(int i=ln;i<=rn;i++)

if(x[p[i]]*z[s[l]]+y[p[i]]>k[s[l]])p1[++cnt1]=p[i];

else p2[++cnt2]=p[i];

} for(int i=1;i<=cnt1;i++)p[i+ln-1]=p1[i];

for(int i=1;i<=cnt2;i++)p[ln+cnt1+i-1]=p2[i];

solve(ln,ln+cnt1-1,lm,mid);

solve(ln+cnt1,rn,mid+1,rm);

return;

}int main()

for(int i=1;i<=m;i++)

solve(1,n,1,m);

for(int i=1;i<=n;i++)

if(f[i]==m)puts("-1");

else printf("%d\n",f[i]);

return 0;

}

雷達裝置 Ybtoj

有n nn個建築物,第i ii個建築物在笛卡爾座標系上的座標為 xi yi x i,y i xi y i 你需要在x xx軸上安裝一些雷達,每個雷達的偵察半徑均為d dd,要求每個建築物都至少被乙個雷達偵測到,求最少要安裝幾個雷達。第一行兩個正整數n,d n,dn,d。接下來n nn行,第i ii行...

YBTOJ 電路維修

思路 乍一看這題,沒有bfs的頭緒 但是,我們想到了spfa 我們可以把地圖中的每個點看成方格,這樣就有 n 1 m 1 個方格 如果兩點之間有線聯通,那它們之間的邊權就是0,否則就為1 然後spfa就可以了 include include include using namespace std i...

YBTOJ 守衛挑戰

有 n 項任務,有乙個數 k 每一項任務成功的概率是 p i 這裡與原題目不同,原題目是百分之 p i 這裡相當於 p i frac 成功後會使 k 加上 a i 問至少成功 l 次且最後 k leq0 的概率是多少。資料範圍 0 leq k leq2000,0 leq l leq n leq 20...