• BZOJ4814,几何


    对每个关键点i,将每个三角形缩成一个线段(因为三角形不相交),然后把线段两端点 和其他关键点一起 以i为中心点 极角排序。

    扫一圈。扫到一个关键点j时, 判断当前最靠近i的线段是否遮盖i到j的路径,  因为对同一个点i,线段之间的相对关系是不变的,所以可以用堆维护加线段删线段,

     1 #include <bits/stdc++.h>
     2 #define LL long long
     3 using namespace std;
     4 int T,n,m,p,q,k,t,x,y,z,ans,d[2005],e[1005];
     5 struct node{int x,y,d;}a[4005],b[4005],c[1005][3];
     6 LL operator *(node a,node b){return (LL)a.x*b.y-(LL)a.y*b.x;}
     7 node operator -(node a,node b){return (node){a.x-b.x,a.y-b.y,a.d};}
     8 bool hi(int u,int v){ // v是不是比u更接近中心点
     9     LL x=(c[v][0]-c[u][0])*(c[u][2]-c[u][0]),y=(c[v][2]-c[u][0])*(c[u][2]-c[u][0]);
    10     if (x>=0&&y>=0) return 0; if (x<=0&&y<=0) return 1;
    11     return (c[u][0]-c[v][0])*(c[v][2]-c[v][0])>=0&&(c[u][2]-c[v][0])*(c[v][2]-c[v][0])>=0;
    12 }
    13 bool cmp(node u,node v){ LL x=(u-a[1])*(v-a[1]); if (!x) return u.d>v.d; else return x>0;}
    14 void join(int x){
    15     int i=++T;
    16     while (i>1&&hi(d[i>>1],x)) e[d[i]=d[i>>1]]=i,i>>=1;
    17     d[i]=x; e[x]=i;
    18 }
    19 void del(int x){
    20     if (e[x]==T) {e[x]=d[T--]=0; return;}
    21     int i=e[x]; e[x]=0; x=d[i]=d[T]; d[T--]=0;
    22     while (i>1&&hi(d[i>>1],x)) e[d[i]=d[i>>1]]=i,i>>=1;
    23     while (i<<1<=T&&hi(x,d[i<<1])||i<<1<T&&hi(x,d[i<<1^1]))
    24     i<<1==T||hi(d[i<<1^1],d[i<<1])?
    25     (e[d[i]=d[i<<1]]=i,i<<=1):(e[d[i]=d[i<<1^1]]=i,i=i<<1^1);
    26     d[i]=x; e[x]=i;
    27 }
    28 int main(){
    29     scanf("%d%d",&n,&m); if (n==1) {puts("0"); return 0;}
    30     for (t=1;t<=n;++t) scanf("%d%d",&a[t].x,&a[t].y);
    31     for (int i=1;i<=m;++i)
    32         for (int j=0;j<3;++j)
    33         a[++t].d=i,scanf("%d%d",&a[t].x,&a[t].y),c[i][j]=a[t];
    34     t=n+m+m;
    35     for (int i=1;i<=n;++i){
    36         while (T) e[d[T]]=0,d[T--]=0;
    37         swap(a[i],a[1]); p=1; q=t+1; b[1]=a[1];
    38         for (int j=2;j<=n;++j) a[j].x<a[1].x?b[++p]=a[j]:b[--q]=a[j];
    39         for (int j=1;j<=m;++j){
    40             sort(c[j],c[j]+3,cmp);
    41             c[j][0].x<a[1].x?b[++p]=c[j][0]:b[--q]=c[j][0];
    42             c[j][2].x<a[1].x?(b[++p]=c[j][2],b[p].d*=-1):(b[--q]=c[j][2],b[q].d*=-1);
    43         }    
    44         if (2<=p) sort(b+2,b+p+1,cmp); 
    45         if (p<t)sort(b+p+1,b+t+1,cmp);
    46         for (int j=1;j<=m;++j) 
    47          if ((c[j][0]-a[1])*(b[2]-a[1])>0&&(c[j][2]-a[1])*(b[2]-a[1])<=0) join(j);
    48         for (int j=2;j<=t;++j)
    49             if (!b[j].d){
    50                 if (!T||(c[d[1]][2]-c[d[1]][0])*(b[j]-c[d[1]][0])>0) ++ans;
    51             }else
    52             if (b[j].d>0) join(b[j].d); else del(-b[j].d);
    53     }
    54     printf("%d",ans>>1);
    55     return 0;
    56 }
    秋姉妹のなく頃に

    n^2*log*计算几何自带大常数。。。然而跑的还算挺快的

  • 相关阅读:
    inotify+rsync做实时同步
    JAVA序列化和反序列化
    初识iBatis
    《Spring in action》之高级装配
    《Spring in action》之装配Bean
    原根
    数论知识
    线性(欧拉)筛
    Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution
    Fibonacci
  • 原文地址:https://www.cnblogs.com/cyz666/p/6811634.html
Copyright © 2020-2023  润新知