4.9 省选模拟赛 圆圈游戏 树形dp set优化建图


由于圆不存在相交的关系 所以包容关系形成了树的形态 其实是一个森林 不过加一个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优化建图的更多相关文章
- 4.3 省选模拟赛 序列游戏 dp
可以发现 某一段被删除后状态难以表示 也难以链接起来. 考虑暴力 有40分的状压dp 暴力存状态 然后枚举转移即可.最后注意和f[0]这个状态取max 不然一分都没有. const int MAXN= ...
- 省选模拟赛 4.26 T1 dp 线段树优化dp
LINK:T1 算是一道中档题 考试的时候脑残了 不仅没写优化 连暴力都打挂了. 容易发现一个性质 那就是同一格子不会被两种以上的颜色染.(颜色就三种. 通过这个性质就可以进行dp了.先按照左端点排序 ...
- 5.29 省选模拟赛 树的染色 dp 最优性优化
LINK:树的染色 考场上以为这道题要爆蛋了 没想到 推出正解来了. 反正是先写了爆搜的 爆搜最近越写越熟练了 容易想到dp 容易设出状态 f[i][j]表示以i为根的子树内白色的值为j此时黑色的值怎 ...
- 5.15 省选模拟赛 容斥 生成函数 dp
LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...
- 4.26 省选模拟赛 T3 状压dp 差分求答案
LINK:T3 比较好的题目 考试的时候被毒瘤的T2给搞的心态爆炸 这道题连正解的思路都没有想到. 一看到题求删除点的最少个 可以使得不连通. 瞬间想到最小割 发现对于10分直接跑最小割即可. 不过想 ...
- 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat
好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...
- 4.2 省选模拟赛 流浪者 容斥dp
求出期望 所有情况很好搞 C(n+m-2,n-1). 也就是说求出所有情况的和乘以上面总方案的逆元即可. 可以发现所有情况和经过多少个障碍点有关 和所处位置无关. 简单的设f[i]表示从1,1到n,m ...
- Contest Hunter 模拟赛09 C [树形dp+差分]
题面 传送门 思路 又双叒叕是一道差分题我没想出来......记录一下 首先这个"所有祖先都比自己小"等价于"父亲比自己小" 这题的基础dp方程很显然,$dp[ ...
- CSP模拟赛 Repulsed(树形DP)
题面 ⼩ w ⼼⾥的⽕焰就要被熄灭了. 简便起⻅,假设⼩ w 的内⼼是⼀棵 n − 1 条边,n 个节点的树. 现在你要在每个节点⾥放⼀些个灭⽕器,每个节点可以放任意多个. 接下来每个节点都要被分配给 ...
随机推荐
- SpringCloud系列之集成分布式事务Seata应用篇
目录 前言 项目版本 项目说明 Seata服务端部署 Seata客户端集成 cloud-web module-order module-cart module-goods module-wallet ...
- 记一次实际开发过程中遇到事务报错问题 Transaction synchronization is not active
一:问题场景 在一次http请求的后台接口中返回结果中出现了这个错误信息“Transaction synchronization is not active”,意思是“事务同步器没有激活”,但是被调用 ...
- asp.net mvc企业实战技能汇总
- Spring源码解析——核心类介绍
前言: Spring用了这么久,虽然Spring的两大核心:IOC和AOP一直在用,但是始终没有搞懂Spring内部是怎么去实现的,于是决定撸一把Spring源码,前前后后也看了有两边,很多东西看了就 ...
- mongodb(一):数据库安装,部署(windows)
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/10885038.html,多谢~=.= 安装MongoDB 双击运行msi文件,一直“Next”. ...
- JS 判断是否为数字 数字型特殊值
JS 数字型三个特殊值 Infinity ,代表无穷大,大于任何数值 -Infinity ,代表无穷小,小于任何数值 NaN ,Not a number,代表一个非数值 isNaN的使用: isNa ...
- Python数据分析实战:使用pyecharts进行数据可视化
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:刘早起 开始使用 基本套路就是先创建一个你需要的空图层,然后使用.s ...
- 2019CSP-J T4 加工零件
题目描述 凯凯的工厂正在有条不紊地生产一种神奇的零件,神奇的零件的生产过程自然也很神奇.工厂里有 n 位工人,工人们从 1 ∼n 编号.某些工人之间存在双向的零件传送带.保证每两名工人之间最多只存在一 ...
- Java对象创建模式
创建Java对象时,对于可为空的属性,创建对象的时候有3种模式:重叠构造器模式.JavaBeans模式.Builder模式(推荐).Stream模式(推荐). ...
- 线性dp 之 奶牛渡河
题目描述 Farmer John以及他的N(1 <= N <= 2,500)头奶牛打算过一条河,但他们所有的渡河工具,仅仅是一个木筏. 由于奶牛不会划船,在整个渡河过程中,FJ必须始终在木 ...