zoukankan      html  css  js  c++  java
  • 102001 E

    x轴上方给你n个点,m个水平杆子,

    然后q组询问,每次询问一个点,问能看到多少个点。

    n,q<=40000,m<=5

    自闭了呀,又写了个 for(int i=1;i<(1<<m)-1;i++) 然后找了两个小时呀。

    怎么这么强烈的即视感。。。

    妙啊!这道题!太他妈的妙了啊!

    我们注意到m很小,这不禁引起了我们的思考,把我头打断了也思考不出来啊,难道我们要枚举直线的子集?

    考虑枚举子集,我们计算这个点,被这个子集中所有线段都能挡住的在x轴上的[l,r]这样的范围。

    不能全挡住就丢掉。

    对于所有的子集的L,R全存下来然后排个序。

    然后我们对于一个查询,

    也对所有的子集考虑这个范围,然后我们对这个[l,r]二分,

    二分到的L的下标减去二分到的R的下标就是在覆盖了[l,r]的点的个数,

    也就是对于这个子集,有这些点是不可视的。

    然后进行简单容斥,奇数加,偶数减,就能得出来总的不可视的,

    最后用n减去这个数就行了

    妙啊!!!

    怎么这么妙啊!

    不需要什么乱七八糟的板子,一道绝妙的题!

     1 //
     2 // Created by gtx1080 on 2019-05-01.
     3 //
     4 #include <bits/stdc++.h>
     5 #define pb push_back
     6 using namespace std;
     7 typedef double db;
     8 const db eps = 1e-9;
     9 const db pi = acos(-1);
    10 int sign(db k){
    11     if (k>eps) return 1; else if (k<-eps) return -1; return 0;
    12 }
    13 int cmp(db k1,db k2){return sign(k1-k2);}
    14 struct point {
    15     db x,y;
    16     point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
    17     point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
    18     point operator * (db k1) const{return (point){x*k1,y*k1};}
    19     db abs2(){return x*x+y*y;}
    20 };
    21 db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
    22 db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
    23 struct line{
    24     point p[2];
    25     line(point k1,point k2){p[0]=k1; p[1]=k2;}
    26     point& operator [] (int k){return p[k];}
    27 };
    28 int n,m,q,c[32];
    29 vector<line> l;
    30 point p[40005];
    31 vector<line> w[32];
    32 vector<db> L[32],R[32];
    33 point inclux(point a,line b){
    34     return {a.x-(a.x-b[0].x)/(a.y-b[0].y)*a.y,a.x-(a.x-b[1].x)/(a.y-b[1].y)*a.y};
    35 }
    36 point inter(point a,vector<line> b){//区间
    37     point ret = {-1e18,1e18};
    38     for(auto x:b){
    39         point tmp = inclux(a,x);
    40         ret.x = max(tmp.x,ret.x);
    41         ret.y = min(tmp.y,ret.y);
    42     }
    43     return ret;
    44 }
    45 bool is_above(point p,vector<line> l){
    46     for(auto x:l)if(cmp(p.y,x[0].y)<=0)return false;
    47     return true;
    48 }
    49 int slove(point q,int now){
    50     point cut = inter(q,w[now]);
    51     if(cmp(cut.x,cut.y)<=0){
    52         int id1 = upper_bound(L[now].begin(),L[now].end(),cut.x+eps)-L[now].begin();
    53         int id2 = lower_bound(R[now].begin(),R[now].end(),cut.y-eps)-R[now].begin();
    54         return id1-id2;
    55     }
    56     return 0;
    57 }
    58 int main(){
    59 //    freopen("/Users/gtx1080/Downloads/04.txt","r",stdin);
    60 //    freopen("/Users/gtx1080/Downloads/04.out","w",stdout);
    61     scanf("%d%d%d",&n,&m,&q);
    62     for(int i=1;i<=n;i++){
    63         scanf("%lf%lf",&p[i].x,&p[i].y);
    64     }
    65     db x1,x2,y;
    66     for(int i=0;i<m;i++){
    67         scanf("%lf%lf%lf",&x1,&x2,&y);
    68         l.pb(line({x1,y},{x2,y}));
    69     }
    70     for(int i=1;i<(1<<m);i++){
    71         c[i]=__builtin_popcount(i)%2==1?1:-1;
    72         for(int j=0;j<m;j++) if(i&(1<<j))w[i].push_back(l[j]);
    73     }
    74     for(int i=1;i<(1<<m);i++){
    75         for(int j=1;j<=n;j++){
    76             if(is_above(p[j],w[i])){
    77                 point cut = inter(p[j],w[i]);
    78                 if(cmp(cut.x,cut.y)<=0){
    79                     L[i].push_back(cut.x);
    80                     R[i].push_back(cut.y);
    81                 }
    82             }
    83         }
    84         sort(L[i].begin(),L[i].end());
    85         sort(R[i].begin(),R[i].end());
    86     }
    87 //    for(auto x:l)printf("%.11f %.11f %.11f
    ",x[0].x,x[1].x,x[0].y);
    88     point x;
    89     while (q--){
    90         scanf("%lf%lf",&x.x,&x.y);
    91         int ans = 0;
    92         for(int j=1;j<(1<<m);j++){
    93             ans+=c[j]*slove(x,j);//挡到的
    94         }
    95         ans=n-ans;
    96         printf("%d
    ",ans);
    97     }
    98 }
    View Code
  • 相关阅读:
    C#定时执行任务
    C#判断数据库是否可连接(PING)
    Excel之导入数据
    JQuery之杂项方法$.grep()
    .Net EF 之代码生成策略
    平台与WeLink深度融合技术汇总
    Host is not allowed to connect to this MySQL
    excel中过长的数字怎么筛选重复项
    oracle 函数大全
    WinXP添加TLS1.1、TLS1.2支持
  • 原文地址:https://www.cnblogs.com/MXang/p/10800865.html
Copyright © 2011-2022 走看看