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减去这个数就行了

妙啊!!!

怎么这么妙啊!

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

 //
// Created by gtx1080 on 2019-05-01.
//
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
typedef double db;
const db eps = 1e-;
const db pi = acos(-);
int sign(db k){
if (k>eps) return ; else if (k<-eps) return -; return ;
}
int cmp(db k1,db k2){return sign(k1-k2);}
struct point {
db x,y;
point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
point operator * (db k1) const{return (point){x*k1,y*k1};}
db abs2(){return x*x+y*y;}
};
db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;}
db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;}
struct line{
point p[];
line(point k1,point k2){p[]=k1; p[]=k2;}
point& operator [] (int k){return p[k];}
};
int n,m,q,c[];
vector<line> l;
point p[];
vector<line> w[];
vector<db> L[],R[];
point inclux(point a,line b){
return {a.x-(a.x-b[].x)/(a.y-b[].y)*a.y,a.x-(a.x-b[].x)/(a.y-b[].y)*a.y};
}
point inter(point a,vector<line> b){//区间
point ret = {-1e18,1e18};
for(auto x:b){
point tmp = inclux(a,x);
ret.x = max(tmp.x,ret.x);
ret.y = min(tmp.y,ret.y);
}
return ret;
}
bool is_above(point p,vector<line> l){
for(auto x:l)if(cmp(p.y,x[].y)<=)return false;
return true;
}
int slove(point q,int now){
point cut = inter(q,w[now]);
if(cmp(cut.x,cut.y)<=){
int id1 = upper_bound(L[now].begin(),L[now].end(),cut.x+eps)-L[now].begin();
int id2 = lower_bound(R[now].begin(),R[now].end(),cut.y-eps)-R[now].begin();
return id1-id2;
}
return ;
}
int main(){
// freopen("/Users/gtx1080/Downloads/04.txt","r",stdin);
// freopen("/Users/gtx1080/Downloads/04.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
for(int i=;i<=n;i++){
scanf("%lf%lf",&p[i].x,&p[i].y);
}
db x1,x2,y;
for(int i=;i<m;i++){
scanf("%lf%lf%lf",&x1,&x2,&y);
l.pb(line({x1,y},{x2,y}));
}
for(int i=;i<(<<m);i++){
c[i]=__builtin_popcount(i)%==?:-;
for(int j=;j<m;j++) if(i&(<<j))w[i].push_back(l[j]);
}
for(int i=;i<(<<m);i++){
for(int j=;j<=n;j++){
if(is_above(p[j],w[i])){
point cut = inter(p[j],w[i]);
if(cmp(cut.x,cut.y)<=){
L[i].push_back(cut.x);
R[i].push_back(cut.y);
}
}
}
sort(L[i].begin(),L[i].end());
sort(R[i].begin(),R[i].end());
}
// for(auto x:l)printf("%.11f %.11f %.11f\n",x[0].x,x[1].x,x[0].y);
point x;
while (q--){
scanf("%lf%lf",&x.x,&x.y);
int ans = ;
for(int j=;j<(<<m);j++){
ans+=c[j]*slove(x,j);//挡到的
}
ans=n-ans;
printf("%d\n",ans);
}
}

最新文章

  1. Apache Cordova开发Android应用程序——番外篇
  2. 用winform程序来了解委托和事件
  3. 让网站动起来!12款优秀的 jQuery 动画插件推荐
  4. CentOS 7 程序自启动的问题
  5. 【即时通讯】即时通讯及XMPP概述及…
  6. C# 中 SQLite 使用介绍
  7. &lt;实训|第八天&gt;超级管理员管理linux用户行为权限附监控主机状态
  8. C# 无边框窗体的最小化问题
  9. Android 使用Application总结
  10. 记录CentOS 7.4 上安装MySQL&amp;MariaDB&amp;Redis&amp;Mongodb
  11. nginx暴露目录文件
  12. The.Glory.of.Innovation 创新之路3放飞好奇
  13. XSS笔记
  14. JAVA连接数据库 #03# HikariCP
  15. 让你真正了解chmod和chown命令的用法
  16. MySQL优化之profile
  17. android实现log日志输出
  18. (转)Linux系统stat指令用法
  19. c++ 操作符优先级
  20. HDU 1033 Edge[地图型模拟/给你一串字符串,A代表以此点为参照顺时针90&#176;,V代表逆时针90&#176;]

热门文章

  1. 正交表生成工具 PICT 成对组合覆盖 收藏
  2. 新姿势!Redis中调用Lua脚本以实现原子性操作
  3. sql遍历查询结果sql循环查询结果集sql循环查询
  4. CF959E Mahmoud and Ehab and the xor-MST 思维
  5. winfom实现关闭后一直运行
  6. xampp 在 windows下 配置 fcgi... 和 opcache 等 优化操作
  7. Kibana6.x.x——导航权限控制入门
  8. hdu3038判断区间谎言(带权并查集)
  9. md5,base64加密
  10. python3 关键字和可变参数笔记