FJ省队集训DAY2 T2




思路:我们可以考虑三角剖分,这样问题就变成考虑三角形的选取概率和三角形内有多少个点了。
先用树状数组预处理出三角剖分的三角形中有多少个点,然后用线段树维护,先用原点极角排序,然后枚举i,再以i极角排序,此时线段树的作用就来了,每次到一个询问的教室点,我们就在线段树里面查找之前的概率,统计贡献即可。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define MAXN 2005
struct Point{
double x,y;
double p,ang;
int id;
}p[MAXN],Cur[MAXN];
double P[MAXN],T[MAXN * ];
int n,m,rk[MAXN],s[MAXN],f[MAXN][MAXN];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
bool cmp(Point p1,Point p2){
return p1.ang<p2.ang;
}
void build (int k,int l,int r){
if (l==r) {T[k]=-P[Cur[l].id];return;}
int mid=(l+r)>>;
build(k*,l,mid);
build(k*+,mid+,r);
T[k]=T[k*]*T[k*+];
}
double query(int k,int l,int r,int x,int y){
if (y<l||x>r) return 1.0;
if (x<=l&&r<=y) return T[k];
int mid=(l+r)>>;
return query(k*,l,mid,x,y)*query(k*+,mid+,r,x,y);
}
void init(){
n=read();m=read();
for (int i=;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for (int i=n+;i<=n+m;i++)
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&P[i]);
for (int i=;i<=n+m;i++)
p[i].ang=atan2(p[i].y,p[i].x);
}
void add(int pos){
for (;pos<=n+m;pos+=(pos)&(-pos)) s[pos]++;
}
int sum(int pos){
int res=;
for (;pos;pos-=(pos)&(-pos)) res+=s[pos];
return res;
}
void Sort(int mid){
int tot=;
for (int i=;i<=n+m;i++)
if (i!=mid) Cur[++tot]=p[i],Cur[tot].ang=atan2(Cur[tot].y-p[mid].y,Cur[tot].x-p[mid].x);
std::sort(Cur+,Cur++tot,cmp);
for (int i=;i<=tot;i++) rk[Cur[i].id]=i;
}
int range(int l,int r){
if (l<=r) return sum(r)-sum(l-);
return sum(n+m)-sum(l-)+sum(r);
}
void solve(){
for (int i=;i<=n+m;i++)
p[i].ang=atan2(p[i].y,p[i].x),p[i].id=i;
std::sort(p+,p++n+m,cmp);
for (int i=;i<=n+m+;i++)
if (p[i].id>n){
Sort(i);
for (int j=;j<=n+m;j++) s[j]=;
for (int j=i+;j<=n+m+;j++){
if (p[j].id<=n&&p[j].id) add(rk[p[j].id]);
f[p[i].id][p[j].id]=std::max(,range(rk[p[j].id],rk[]));
}
for (int j=;j<=n+m;j++) s[j]=;
for (int j=i-;j;j--){
if (p[j].id<=n&&p[j].id) add(rk[p[j].id]);
f[p[i].id][p[j].id]=std::max(,range(rk[],rk[p[j].id]));
}
}
}
double ask(int l,int r){
if (l>r) return query(,,n+m-,l,n+m-)*query(,,n+m-,,r-);
else return query(,,n+m-,l,r-);
}
void linear(){
double ans=0.0;
int tot=;
for (int i=;i<=n+m;i++)
if (p[i].id>n){
tot=;
for (int j=;j<=n+m;j++)
if (i!=j) Cur[++tot]=p[j],Cur[tot].ang=atan2(p[j].y-p[i].y,p[j].x-p[i].x);
std::sort(Cur+,Cur++tot,cmp);
build(,,tot);
for (int j=,Pp=;j<=tot;j++){
for(;(Cur[j].x - p[i].x) * (Cur[Pp].y - p[i].y) - (Cur[j].y - p[i].y) * (Cur[Pp].x - p[i].x) > ;) Pp=Pp%tot+;
if (Cur[j].id>n){
double pr=ask(Pp,j)*P[p[i].id]*P[Cur[j].id];
if (p[i].x * Cur[j].y - p[i].y * Cur[j].x < )
ans -= pr * f[p[i].id][Cur[j].id]; else
ans += pr * f[p[i].id][Cur[j].id];
}
}
}
printf("%.9lf\n",ans);
}
int main(){
init();
solve();
linear();
}
FJ省队集训DAY2 T2的更多相关文章
- FJ省队集训DAY2 T1
思路:转换成n条三维空间的直线,求最大的集合使得两两有交点. 有两种情况:第一种是以某2条直线为平面,这时候只要统计这个平面上有几条斜率不同的直线就可以了 还有一种是全部交于同一点,这个也只要判断就可 ...
- FJ省队集训DAY4 T2
XXX #include<cstdio> #include<iostream> #include<cmath> #include<cstring> #i ...
- FJ省队集训DAY3 T2
思路:如果一个DAG要的路径上只要一条边去切掉,那么要怎么求?很容易就想到最小割,但是如果直接做最小割会走出重复的部分,那我们就这样:反向边设为inf,这样最小割的时候就不会割到了,判断无解我们直接用 ...
- FJ省队集训最终测试 T2
思路:发现如果一个人一共选了x个点,那么选中某一个点对的概率都是一样的,一个人选x个点的总方案是C(n,x),一个人选中某个点对的总方案是C(n-2,x-2),这样,那么选中某个点对的概率就是 x*( ...
- FJ省队集训DAY3 T1
思路:我们考虑如果取掉一个部分,那么能影响到最优解的只有离它最近的那两个部分. 因此我们考虑堆维护最小的部分,离散化离散掉区间,然后用线段树维护区间有没有雪,最后用平衡树在线段的左右端点上面维护最小的 ...
- FJ省队集训DAY1 T1
题意:有一堆兔子,还有一个r为半径的圆,要求找到最大集合满足这个集合里的兔子两两连边的直线不经过圆. 思路:发现如果有两个点之间连边不经过圆,那么他们到圆的切线会构成一段区间,那么这两个点的区间一定会 ...
- FJ省队集训DAY4 T3
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #inclu ...
- FJ省队集训最终测试 T3
思路:状态压缩dp,f[i][j[[k]代表i行j列这个格子,连续的状态为k,这个连续的状态是什么?就是下图 X格子代表我当前走到的地方,而这里的状态就是红色部分,也就是连续的一段n的状态,我们是分每 ...
- FJ省队集训DAY5 T1
思路:考试的时候打了LCT,自以为能过,没想到只能过80.. 考完一想:lct的做法点数是100W,就算是nlogn也会T. 讲一下lct的做法把:首先如果一条边连接的两个点都在同一个联通块内,那么这 ...
随机推荐
- 微信、QQ和手机号之间不得不说的故事!
发文字,发图片,发心情,视频聊天,查看附近的人,微信能干的事情QQ都可以,那么它们有什么区别,我QQ用得好好的为什么要我联系人都导到微信去?我们很早就有了QQ,但是在QQ时代,我们虽然用QQ发消息聊天 ...
- jQuery/CSS3实现图片层叠展开特效
这是一款基于jQuery和CSS3的图片层叠展开特效,让鼠标滑过图片时即可触发这些特效.其中有一款就像扇子展开收拢一样,看起来效果都非常不错.当然本文主要还是来分析一下用jQuery实现这一效果的方法 ...
- 理解JavaScript中的事件处理 阻止冒泡event.stopPropagation();
原文地址:http://www.cnblogs.com/binyong/articles/1750263.html 这篇文章对于了解Javascript的事件处理机制非常好,将它全文转载于此,以备不时 ...
- zookeeper[4] 安装windows zookeeper,及问题处理
安装步骤: 1.在如下路径下载zookeeper-3.4.7.tar.gz http://mirrors.cnnic.cn/apache/zookeeper/stable/ 2.解压zookeeper ...
- JS(四)
JS的属性好多,方法好多,一下子塞进来真的需要时间消化,很多东西都是当时记得很清楚,但忘得很快,看来需要经常去复习,主要是感觉后面一点的练习题好像少了点,所以就显得不是很熟练. 1.About Tim ...
- 转义字符和ASCII
一.字符(char) 数字(int) 屏幕显示 '\n' 10 换行 '\0' ...
- 【性能优化】优化笔记之一:图像RGB与YUV转换优化
本文主要介绍如何优化您自己的CODE,实现软件的加速.我们一个图象模式识别的项目,需要将RGB格式的彩色图像先转换成黑白图像.图像转换的公式如下: Y = 0.299 * R + 0.587 * G ...
- 新手上路Tomcat 7.x和JDK的配置
前言:这段时间又复习了JAVA以前做东西总是在IDE里面好多基础的东西都不知道,这次买了本书让自己重新认识下JAVA! 说明:以前装JDK时,我是和Mars老师学的那种开发JAVA应用程序进行配置的环 ...
- LDAP错误代码221
---------------------------命令方式启动失败报错-------------------------------[root@rusky bin]# ./dsadm start ...
- (六)《Java编程思想》——初始化及类的加载顺序
package chapter7; /** * 初始化及类的加载顺序:顺序如下 * 1.基类的static变量 * 2.导出类的static变量 * 3.基类的变量 * 4.基类的构造函数 * 5.导 ...