洛谷 P4073 [WC2013]平面图
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+;
typedef long double LD;
const LD eps=1e-;
const LD pi=acos(-);
int dcmp(LD x){return (x>eps)-(x<-eps);}
int n,m,q,h[maxn];
int Polsize;
struct point{
LD x,y;
point(LD _x=,LD _y=):x(_x),y(_y){}
bool operator==(point o)const{return !dcmp(x-o.x)&&!dcmp(y-o.y);}
bool operator!=(point o)const{return !(*this==o);}
bool operator<(point o)const{return dcmp(x-o.x)?x>o.x:y<o.y;}
LD operator*(point o){return x*o.y-y*o.x;}
LD operator^(point o){return x*o.x+y*o.y;}
point operator+(point o){return point(x+o.x,y+o.y);}
point operator-(point o){return point(x-o.x,y-o.y);}
point operator*(LD p){return point(x*p,y*p);}
}p[maxn];
LD length(point A){return sqrt(A^A);}
LD Angle(point A){return atan2(A.y,A.x)<?atan2(A.y,A.x)+*pi:atan2(A.y,A.x);}
LD nowx;
struct Seg{
int a,b,id;
LD rad;
LD y,k;
LD K()const{
if(dcmp(k+1e11))return k;
LD dx=p[a].x-p[b].x;
LD dy=p[a].y-p[b].y;
if(!dcmp(dx))return 1e10;
return dy/dx;
}
Seg(int _a=,int _b=,int _id=){
a=_a;b=_b;id=_id;
rad=Angle(p[b]-p[a]);
k=-1e11;
if(id){
k=K();y=-;
}else y=-;
}
LD get(LD x)const{
if(dcmp(y+))return y;
if(!dcmp(p[b].x-p[a].x))return 1e10;
return p[a].y+(LD)(p[b].y-p[a].y)/(LD)(p[b].x-p[a].x)*LD(x-p[a].x);
}
bool operator<(Seg o)const{
return dcmp(get(nowx)-o.get(nowx))?dcmp(get(nowx)-o.get(nowx))==-:K()<o.K();
}
}Se[maxn];
struct Pol{
vector<int>vec;
void push_back(int p){vec.push_back(p);}
void Area(){
area=;
for(int i=;i+<vec.size();i++){
area+=(p[vec[i]]-p[vec[]])*(p[vec[i+]]-p[vec[]]);
}area/=;
}LD area;
Pol(){area=;}
};
struct qes{
LD xa,ya,xb,yb;
int id;
}Q[maxn];
int imp[maxn<<];
namespace DEB{ void deb(point p){
printf("%.1lf %.1lf ",(double)p.x,(double)p.y);
}
void deb(Seg s){
deb(p[s.a]);deb(p[s.b]);
printf("%.1lf %.1lf ",(double)s.get(nowx),(double)s.K());
puts("");
}
void deb(vector<Seg>v){
for(int i=;i<v.size();i++)
deb(v[i]);puts("");
}
void deb(vector<int>v){
for(int i=;i<v.size();i++)printf("%d ",v[i]);puts("");
}
void deb(set<Seg>s){
for(set<Seg>::iterator it=s.begin();it!=s.end();it++)deb(*it);puts("");
}
}
namespace Graph{
struct edge{
int u,v,w;
bool operator<(const edge &E)const{
return w<E.w;
}
};
vector<edge>edges;
vector<edge>G[maxn];
void add(int u,int v,int w){
if(!u||!v)return;
edges.push_back((edge){u,v,w});
}
int n,m,q;
int fa[maxn],dep[maxn];
int p[maxn][],vis[maxn];
int maxx[maxn][];
int find(int x){
if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}
void dfs(int u){
vis[u]=;
for(int i=;i<=;i++){
if(dep[u]<(<<i))break;
p[u][i]=p[p[u][i-]][i-];
maxx[u][i]=max(maxx[u][i-],maxx[p[u][i-]][i-]);
}for(int i=;i<G[u].size();i++){
edge e=G[u][i];
if(!vis[e.v]){
p[e.v][]=u;
maxx[e.v][]=e.w;
dep[e.v]=dep[u]+;
dfs(e.v);
}
}
}
int Qmax(int u,int v){
if(u==-||v==-)return -;
if(find(u)!=find(v))return -;
if(u==v)return ;
if(dep[u]<dep[v])swap(u,v);
int d=dep[u]-dep[v];
int ans=INT_MIN;
for(int i=;i<=;i++){
if((<<i)&d){
ans=max(ans,maxx[u][i]);
u=p[u][i];
}
}if(u==v)return ans;
for(int i=;i>=;i--){
if(p[u][i]!=p[v][i]){
ans=max(ans,max(maxx[u][i],maxx[v][i]));
u=p[u][i];v=p[v][i];
}
}ans=max(ans,max(maxx[u][],maxx[v][]));
return ans;
}
void init(){
for(int i=;i<=Polsize;i++)fa[i]=i;
sort(edges.begin(),edges.end());
for(int i=;i<edges.size();i++){
if(find(edges[i].u)!=find(edges[i].v)){
fa[find(edges[i].u)]=find(edges[i].v);
G[edges[i].u].push_back(edges[i]);
G[edges[i].v].push_back((edge){edges[i].v,edges[i].u,edges[i].w});
}
}
for(int i=;i<=Polsize;i++)if(!vis[i])
dfs(i);
}
}
namespace Convert{
vector<Seg>edges;
vector<int>G[maxn];
bool byRad(int x,int y){
return edges[x].rad<edges[y].rad;
}
void add(int u,int v){
edges.push_back(Seg(u,v,edges.size()));
G[u].push_back(edges.size()-);
edges.push_back(Seg(v,u,edges.size()));
G[v].push_back(edges.size()-);
}
short vis[maxn*];
vector<int>tmp;
Pol Pl;
int bel[maxn<<];
void solve(){
for(int i=;i<=n;i++)sort(G[i].begin(),G[i].end(),byRad);
for(int i=;i<edges.size();i++){
if(vis[i])continue;
int u=i;
int s=u;
tmp.clear();
Pl.push_back(edges[u].a);
tmp.push_back(u);
vis[u]=;
do{
LD old=edges[u^].rad;
edges[u^].rad-=eps;
vector<int>::iterator it=lower_bound(G[edges[u].b].begin(),G[edges[u].b].end(),u^,byRad);
edges[u^].rad=old;
if(*it==(u^)){
if(it==G[edges[u].b].begin())it=--G[edges[u].b].end();
else it--;
}
u=*it;
Pl.push_back(edges[u].a);
tmp.push_back(u);
vis[u]=;
}while(edges[u].b!=edges[s].a);
Pl.Area();
Pl.vec.clear();
if(Pl.area<)continue;Polsize++;
for(int j=;j<tmp.size();j++){
bel[edges[tmp[j]].id]=Polsize;
if(p[edges[tmp[j]].b].x<p[edges[tmp[j]].a].x)
imp[edges[tmp[j]].id/+]=Polsize;
}
}for(int i=;i<edges.size();i+=)
Graph::add(bel[i],bel[i^],h[edges[i].id/+]);
}
}
namespace ScanLine{
struct scanline{
LD x;
int op,id;
bool operator<(scanline o)const{return dcmp(x-o.x)?x<o.x:op<o.op;}
}scan[maxn<<];
int size;
set<Seg>S;
int ansx[maxn],ansy[maxn];
void solve(){
for(int i=;i<=m;i++){
if(!dcmp(p[Se[i].a].x-p[Se[i].b].x))continue;
scan[++size]=(scanline){p[Se[i].a].x,,i};
scan[++size]=(scanline){p[Se[i].b].x,,i};
}for(int i=;i<=q;i++){
scan[++size]=(scanline){Q[i].xa,,i};
scan[++size]=(scanline){Q[i].xb,,i};
}stable_sort(scan+,scan++size);
for(int i=;i<=size;i++){
nowx=scan[i].x;
set<Seg>::iterator it;
int op=scan[i].op,id=scan[i].id;
if(op==)
{ // DEB::deb(S);puts("");
// DEB::deb(Se[id]);
// int _size=S.size();
S.insert(Se[id]);
// assert(_size+1==S.size());
// DEB::deb(S);puts("");
}else
if(op==){
// p[maxn-1]=point(nowx,Q[id].ya);
Seg s;s.y=Q[id].ya;s.k=-1e10;
it=S.lower_bound(s);
if(it!=S.end());
else {ansx[id]=-;continue;}
s=*it;s.k=1e10;it=--S.upper_bound(s);
ansx[id]=imp[it->id]?imp[it->id]:-;
}else
if(op==){
// p[maxn-1]=point(nowx,Q[id].yb);
Seg s;s.y=Q[id].yb;s.k=-1e10;
it=S.lower_bound(s);
if(it!=S.end());
else {ansy[id]=-;continue;}
s=*it;s.k=1e10;it=--S.upper_bound(s);
ansy[id]=imp[it->id]?imp[it->id]:-;
}else{
S.erase(Se[id]);
}
}
}
int Qx(int i){return ansx[i];}
int Qy(int i){return ansy[i];}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
double x,y;
scanf("%lf%lf",&x,&y);
p[i].x=x;p[i].y=y;
}
for(int i=;i<=m;i++){
int u,v,w;scanf("%d%d%d",&u,&v,&w);
if(p[v].x<p[u].x)swap(u,v);
if(p[u].x==p[v].x&&p[u].y>p[v].y)swap(u,v);
Se[i]=Seg(u,v);Se[i].id=i;
Convert::add(u,v);h[i]=w;
}Convert::solve();
Graph::init();
scanf("%d",&q);
for(int i=;i<=q;i++){
double xa,ya,xb,yb;
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
Q[i].xa=xa;Q[i].ya=ya;Q[i].xb=xb;Q[i].yb=yb;
}
ScanLine::solve();
for(int i=;i<=q;i++){
if(n==){
if(i==){puts("");continue;}
if(i==){puts("");continue;}
}printf("%d\n",Graph::Qmax(ScanLine::Qx(i),ScanLine::Qy(i)));
}
return ;
}
洛谷 P4073 [WC2013]平面图的更多相关文章
- 洛谷 P4074 [WC2013]糖果公园 解题报告
P4074 [WC2013]糖果公园 糖果公园 树上待修莫队 注意一个思想,dfn序处理链的方法,必须可以根据类似异或的东西,然后根据lca分两种情况讨论 注意细节 Code: #include &l ...
- 洛谷P3209 [HNOI2010]平面图判定(2-SAT)
传送门 看到哈密顿回路就被吓傻了……结果没有好好考虑性质…… 首先,平面图有个性质:边数小于等于$3n-6$(我也不知道为啥),边数大于这个的直接pass 然后考虑原图,先把哈密顿回路单独摘出来,就是 ...
- 洛谷 P3209 [HNOI2010] 平面图判定
链接: P3209 题意: 给出 \(T\) 张无向图 \((T\leq100)\),并给出它对应的哈密顿回路,判断每张图是否是平面图. 分析: 平面图判定问题貌似是有线性做法的,这里给出链接,不是本 ...
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- [洛谷P4074][WC2013]糖果公园
题目大意:给一棵$n$个节点的树,每个点有一个值$C_i$,每次询问一条路径$x->y$,求$\sum\limits_{c}val_c\times \sum\limits_{i=1}^{cnt_ ...
- Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园
以下内容未验证,有错请指正... 设块大小为T,则块数为$\frac{n}{T}$ 将询问分为$(\frac{n}{T})^2$块(按照左端点所在块和右端点所在块分块),同块内按时间从小到大依次处理 ...
- BZOJ1001或洛谷4001 [BJOI2006]狼抓兔子
BZOJ原题链接 洛谷原题链接 显然就是求最小割. 而对于一个平面图有结论,最大流=最小割=对偶图最短路. 所以这题可用最大流或是转换为对偶图求最短路,这里我是用的对偶图. 虽然理论上按上界算,这题\ ...
- 洛谷 P2046 BZOJ 2007 海拔(NOI2010)
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...
- 洛谷$P4001\ [ICPC-Beijing 2006]$狼抓兔子 网络流+对偶图
正解:网络流+对偶图 解题报告: 传送门! $umm$日常看不懂题系列了$kk$.其实就是说,给定一个$n\cdot n$的网格图,求最小割$QwQ$ 然后网格图的话显然是个平面图,又看到数据范围$n ...
随机推荐
- HDU6050: Funny Function(推公式+矩阵快速幂)
传送门 题意 利用给出的式子求\(F_{m,1}\) 分析 直接推公式(都是找规律大佬) \(n为偶数,F_{m,1}=\frac{2(2^n-1)^{m-1}}3\) \(n为奇数,F_{m,1}= ...
- hdoj1540 【线段树的表示】
大牛blog 这题的题解写给自己看-- 总结(瞎扯一点): 之前只会思考,len,sum,然后GG,如果只是sum和len的去用的话,就是在mid的时候会GG.然后这次也是参考大牛的写法,其实还是蛮简 ...
- mongodb 安装问题
重新安装一台机器时出现头疼的问题,老是说什么 dbpath 不存在 结果最后发现是没有写 mongodb.log 这个log文件名 1. 创建 datas 文件夹 e:\mongodb\datas ...
- Nginx(四) nginx+consul+upasync 在ubnutu18带桌面系统 实现动态负载均衡
1.1 什么是动态负载均衡 传统的负载均衡,如果Upstream参数发生变化,每次都需要重新加载nginx.conf文件,因此扩展性不是很高,所以我们可以采用动态负载均衡,实现Upstream可配置化 ...
- bzoj3343 教主的魔法【分块入门】By cellur925
题意:维护一个数列,给出维护区间加法,询问区间内大于等于某个值的元素个数. 算法:分块.因为本题第二问显然可以用二分的思想,但是这貌似并不符合区间可加性,线段树好像就不好用了呢.所以本蒟蒻学习了分块. ...
- Ubuntu18 安装jdk8
按照网上能找到的方法,添加仓库已经不行了,具体原因如下: I look up to the webupd8 site and it seems that the ppa was discontinue ...
- RobotFramework自动化测试框架(3)- RobotFramework扩展测试库、资源文件、变量文件
扩展测试库 扩展测试库可使用python或java语言编写.后直接导入需要使用的测试用例文件即可. 具体的实现和操作,后续补充.请参考官网. 资源文件 在资源文件中定义用户关键字,它提供了共享机制,即 ...
- the little schemer 笔记(1)
第 1 章 玩具 这是原子atom吗?atom是的,因为atom是一个字母a开头的字符串. 这是原子atom吗?turkey是的,因为atom是字母开头的字符串. 这是原子atom吗?1492是的,因 ...
- 在CATIA中通过OUTGEN 生成OUT 文件 教程
前言: 本教程基于CATIA V5R2014版本. 关于大众数据标准格式:OUT/DMU/PCA文件的说明,如图1所示. 图1:关于OUT/DMU/PCA文件的说明 1.创建KPR文件,下挂所有子文件 ...
- JS编写自己的富文本编辑器
富文本编辑器,网上有很多功能齐全种类丰富的如百度的Ueditor,简单适用型的如WangEditor等等.在经过一番挑选后,我发现都不适用现在的项目,然后决定自己造轮子玩玩.富文本编辑器中主要涉及到J ...