由于圆不存在相交的关系 所以包容关系形成了树的形态 其实是一个森林 不过加一个0点 就变成了树。

考虑对于每个圆都求出最近的包容它的点 即他的父亲。然后树形dp即可。暴力建图n^2.

const int MAXN=100010;
int n,m,len;
struct wy
{
ll x,y,r,w;
inline int friend operator <(wy a,wy b){return a.r<b.r;}
}t[MAXN];
int f[MAXN];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
inline db dist(int x,int y){return sqrt((pf(t[x].x-t[y].x)+pf(t[x].y-t[y].y))*1.0);}
inline void dp(int x)
{
f[x]=t[x].w;
int sum=0;
go(x)
{
dp(tn);
sum+=f[tn];
}
f[x]=max(f[x],sum);
}
inline void add(int x,int y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
int main()
{
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);
get(n);
rep(1,n,i)
{
ll x,y,r,w;
get(x);get(y);
get(r);get(w);
t[i]=(wy){x,y,r,w};
}
sort(t+1,t+1+n);
rep(1,n,i)//对于每个i找到一个最小的j.
{
db minn=INF;int p=0;
rep(i+1,n,j)
{
db d=dist(i,j);
if(t[j].r-t[i].r-d<0)continue;
if(t[j].r-t[i].r-d<minn)
{
minn=t[j].r-t[i].r-d;
p=j;
}
}
add(p,i);
}
dp(0);put(f[0]);return 0;
}

考虑优化建图 一个思路 把所有的边都连上 然后topsort建图 但是这并不能线段树优化建图什么的。

或者直接对于每个圆找到离自己最近的圆然后判断关系连边。

对于后者 可以考虑以扫描线的方式建图 对于每个圆我们都在左边插入 右边删除。

在插入的时候寻找父亲 可以发现此时圆对于离自己最近的圆要么是包含的 要么是兄弟。

对于前者直接找到了父亲 对于后者 兄弟的父亲就是自己的父亲。

考虑找到最近的圆可以使用圆的上半部分来判断 对于上半部分找到自己左端点离自己最近的圆弧 如果是下半圆弧就是兄弟 上半圆弧那么必然是父亲。

用set维护距离 可以发现这些圆弧的相对位置不变 所以总复杂度nlogn.

const ll MAXN=200010,maxn=3000010;
ll n,T,cnt,len;
ll f[MAXN];
ll lin[MAXN],ver[MAXN<<1],nex[MAXN<<1];
struct wy{ll x,y,z,r,id;}t[MAXN];
struct jl{ll x,y,op;}q[MAXN];
inline ll cmp(jl a,jl b){return a.x<b.x;}
inline void dp(ll x)
{
f[x]=t[x].z;
ll sum=0;
go(x)
{
dp(tn);
sum+=f[tn];
}
f[x]=max(f[x],sum);
}
inline void add(ll x,ll y)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
}
struct data
{
ll id,op;
//data(){};
inline double calc()const
{
if(op)return t[id].y+sqrt((pf(t[id].r)-pf(t[id].x-T))*1.0);
return t[id].y-sqrt((pf(t[id].r)-pf(t[id].x-T))*1.0);
}
inline ll friend operator <(data a,data b)
{
double x=a.calc();db y=b.calc();
if(fabs(y-x)>EPS)return x<y;
if(a.op!=b.op)return a.op<b.op;
return a.id<b.id;
}
};
set<data>s;
set<data>::iterator it;
signed main()
{
freopen("circle.in","r",stdin);
freopen("circle.out","w",stdout);
get(n);
rep(1,n,i)
{
ll x,y,z,r;
get(x);get(y);get(r);get(z);
t[i]=(wy){x,y,z,r};
q[++cnt]=(jl){t[i].x-t[i].r,i,1};
q[++cnt]=(jl){t[i].x+t[i].r,i,-1};
}
sort(q+1,q+1+cnt,cmp);
//rep(1,cnt,i)cout<<q[i].y<<endl;
rep(1,cnt,i)
{
T=q[i].x;
//cout<<(*s.begin()).id<<' '<<(*s.begin()).op<<endl;
if(q[i].op==1)
{
s.insert((data){q[i].y,1});
it=s.find((data){q[i].y,1});
++it;
if(it==s.end())f[q[i].y]=0;
else
{
if((*it).op==0)f[q[i].y]=f[(*it).id];
else f[q[i].y]=(*it).id;
}
s.insert((data){q[i].y,0});
}
else
{
s.erase((data){q[i].y,1});
s.erase((data){q[i].y,0});
}
}
rep(1,n,i)add(f[i],i);
dp(0);put(f[0]);return 0;
}

一些细节:两个圆并列的时候注意让下半圆弧优先 注意距离的计算公式。

4.9 省选模拟赛 圆圈游戏 树形dp set优化建图的更多相关文章

  1. 4.3 省选模拟赛 序列游戏 dp

    可以发现 某一段被删除后状态难以表示 也难以链接起来. 考虑暴力 有40分的状压dp 暴力存状态 然后枚举转移即可.最后注意和f[0]这个状态取max 不然一分都没有. const int MAXN= ...

  2. 省选模拟赛 4.26 T1 dp 线段树优化dp

    LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...

  3. 5.29 省选模拟赛 树的染色 dp 最优性优化

    LINK:树的染色 考场上以为这道题要爆蛋了 没想到 推出正解来了. 反正是先写了爆搜的 爆搜最近越写越熟练了 容易想到dp 容易设出状态 f[i][j]表示以i为根的子树内白色的值为j此时黑色的值怎 ...

  4. 5.15 省选模拟赛 容斥 生成函数 dp

    LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...

  5. 4.26 省选模拟赛 T3 状压dp 差分求答案

    LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...

  6. 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat

    好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...

  7. 4.2 省选模拟赛 流浪者 容斥dp

    求出期望 所有情况很好搞 C(n+m-2,n-1). 也就是说求出所有情况的和乘以上面总方案的逆元即可. 可以发现所有情况和经过多少个障碍点有关 和所处位置无关. 简单的设f[i]表示从1,1到n,m ...

  8. Contest Hunter 模拟赛09 C [树形dp+差分]

    题面 传送门 思路 又双叒叕是一道差分题我没想出来......记录一下 首先这个"所有祖先都比自己小"等价于"父亲比自己小" 这题的基础dp方程很显然,$dp[ ...

  9. CSP模拟赛 Repulsed(树形DP)

    题面 ⼩ w ⼼⾥的⽕焰就要被熄灭了. 简便起⻅,假设⼩ w 的内⼼是⼀棵 n − 1 条边,n 个节点的树. 现在你要在每个节点⾥放⼀些个灭⽕器,每个节点可以放任意多个. 接下来每个节点都要被分配给 ...

随机推荐

  1. antd图标库按需加载的插件实现

    前景概要 antd是阿里出品的一款基于antd的UI组件库,使用简单,功能丰富,被广泛应用在中台项目开发中,虽然也出现了彩蛋事故,但不能否认antd本身的优秀,而我们公司在实际工作中也大量使用antd ...

  2. 02 . SaltStack高级用法(Python API)

    Python API简单使用 第一条命令 /usr/bin/salt默认使用的接口是LocalClient,该接口只能在salt master上使用 >>> import salt. ...

  3. 【asp.net core 系列】15 自定义Identity

    0. 前言 在之前的文章中简单介绍了一下asp.net core中的Identity,这篇文章将继续针对Identity进行进一步的展开. 1. 给Identity添加额外的信息 在<[asp. ...

  4. SQLserver-MySQL的区别和用法

    对于程序开发人员而言,目前使用最流行的两种后台数据库即为MySQL and SQL Server.这两者最基本的相似之处在于数据存储和属于查询系统.你可以使用SQL来访问这两种数据库的数据,因为它们都 ...

  5. Disruptor 高性能并发框架二次封装

    Disruptor是一款java高性能无锁并发处理框架.和JDK中的BlockingQueue有相似处,但是它的处理速度非常快!!!号称“一个线程一秒钟可以处理600W个订单”(反正渣渣电脑是没体会到 ...

  6. MYSQL 之 JDBC(三): 增删改查(一)通过Statement执行更新操作

    Statement测试 /** * 通过JDBC向指定的数据表中插入一条记录 * 1. Statement:用于执行sql语句的对象 * 1.1 通过Connection的createStatemen ...

  7. 数据可视化基础专题(十):Matplotlib 基础(二) 自定义配置文件和绘图风格(rcParams和style)

    https://matplotlib.org/api/rcsetup_api.html#module-matplotlib.rcsetup 一.什么是rcParams?我们在使用matplotlibl ...

  8. 定时器之Timer

    Timer中的TimerTask就是一个线程,可以一直执行下去的.可以使用Timer类的cancel方法来结束.-------------------------------------------- ...

  9. Spring Boot 2.x基础教程:EhCache缓存的使用

    上一篇我们学会了如何使用Spring Boot使用进程内缓存在加速数据访问.可能大家会问,那我们在Spring Boot中到底使用了什么缓存呢? 在Spring Boot中通过@EnableCachi ...

  10. 集训 T1-找试场

    大致题意: 按照给定的指令移动,输出最后到达的点. 若没有走动过则输出(0,0). 基本思路 这题就是模拟,主要是判断指令的时候不太好判断, 先用字符串把指令读取进来,看看第一位是否是数字(如果是数字 ...