[BZOJ4049] [Cerc2014] Mountainous landscape(선분 트리 + 돌출 포켓 + 2점)
#include
#include
using namespace std;
typedef long long ll;
int n;
struct Vector{
int x,y;
Vector(int a=0,int b=0):x(a),y(b){}
friend ll operator*(Vector a,Vector b){
return 1ll*a.x*b.y-1ll*b.x*a.y;
}
friend Vector operator-(Vector a,Vector b){
return Vector(a.x-b.x,a.y-b.y);
}
}a[100010];
struct Convex_hull{
vector c;
void insert(Vector a){
for(int j=c.size();j>1&&(a-c[j-2])*(c[j-1]-c[j-2])<=0;j--)
c.pop_back();
c.push_back(a);
return;
}
bool check(Vector a,Vector b){
int l=0,r=c.size()-2;
while(lint mid=(l+r)>>1;
if((c[mid]-a)*(b-a)1]-a)*(b-a))
r=mid;
else l=mid+1;
}
return (c[l]-a)*(b-a)<0||(c[l+1]-a)*(b-a)<0;
}
}tr[400010];
void build(int o,int l,int r){
if(l==r){
tr[o].insert(a[l]);
tr[o].insert(a[l+1]);
return;
}
for(int i=l;i<=r+1;i++)
tr[o].insert(a[i]);
int mid=(l+r)>>1;
build(o<<1,l,mid);
build(o<<1|1,mid+1,r);
return;
}
int query(int o,int l,int r,int L,int R,Vector a,Vector b){
if(L<=l&&r<=R){
if(!tr[o].check(a,b))
return 0;
if(l==r)
return l;
}
int mid=(l+r)>>1,ret=0;
if(L<=mid)
ret=query(o<<1,l,mid,L,R,a,b);
if(!ret&&R>mid)
ret=query(o<<1|1,mid+1,r,L,R,a,b);
return ret;
}
int rd(){
int x=0;
char c;
do c=getchar();
while(!isdigit(c));
do{
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}while(isdigit(c));
return x;
}
int main(){
n=rd();
for(int i=1;i<=n;i++)
a[i].x=rd(),a[i].y=rd();
build(1,1,n-1);
for(int i=1;i<=n-1;i++)
printf("%d ",query(1,1,n-1,i+1,n-1,a[i],a[i+1]));
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
백준 알고리즘 14427번 : 수열과 쿼리 15길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼다. (1 ≤ i ≤ N, 1 ≤ v ≤ 109) 2 : 수열에서 크기가 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.