bzoj 4541: [Hnoi2016]矿区【平面图转对偶图+生成树】
首先平面图转对偶图,大概思路是每条边存正反,每个点存出边按极角排序,然后找每条边在它到达点的出边中极角排序的下一个,这样一定是这条边所属最小多边形的临边,然后根据next边找出所有多边形,用三角剖分计算面积
然后就比较妙了,把对偶图随便搞一个生成树出来,然后对于每个询问,如果一条边是树边,那么如果这条边在树上是向上的就加它子树的和,否则就减
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int N=2000005;
int n,m,k,cnt=1,tot,rt,a[N],fa[N],ne[N],c[N];
long long s1[N],s2[N],ans1,ans2;
bool v[N],vis[N];
struct dian
{
double x,y;
dian(double X=0,double Y=0)
{
x=X,y=Y;
}
dian operator + (const dian &a) const
{
return dian(x+a.x,y+a.y);
}
dian operator - (const dian &a) const
{
return dian(x-a.x,y-a.y);
}
}p[N];
struct bian
{
int x,y,id;
double a;
bian(int X=0,int Y=0,int ID=0)
{
x=X,y=Y,id=ID,a=atan2(p[y].y-p[x].y,p[y].x-p[x].x);
}
bool operator < (const bian &b) const
{
return a<b.a;
}
}b[N];
vector<bian>f[N],g[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
double cj(dian a,dian b)
{
return a.x*b.y-a.y*b.x;
}
long long gcd(long long a,long long b)
{
return !b?a:gcd(b,a%b);
}
void dfs(int u)
{
vis[u]=1;
for(int i=0;i<g[u].size();i++)
if(!vis[g[u][i].y])
{
fa[g[u][i].y]=u;
v[g[u][i].id]=v[g[u][i].id^1]=1;
dfs(g[u][i].y);
s1[u]+=s1[g[u][i].y];
s2[u]+=s2[g[u][i].y];
}
}
int main()
{
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++)
p[i].x=read(),p[i].y=read();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
cnt++;
b[cnt]=bian(x,y,cnt);
f[x].push_back(b[cnt]);
cnt++;
b[cnt]=bian(y,x,cnt);
f[y].push_back(b[cnt]);
}
for(int i=1;i<=n;i++)
sort(f[i].begin(),f[i].end());
for(int i=2;i<=cnt;i++)
{
int nw=lower_bound(f[b[i].y].begin(),f[b[i].y].end(),b[i^1])-f[b[i].y].begin()-1;
if(nw<0)
nw+=f[b[i].y].size();
ne[i]=f[b[i].y][nw].id;
}
for(int i=2;i<=cnt;i++)
if(!c[i])
{
long long mj=0,nw=i,st=b[i].x;
c[i]=++tot;
while(1)
{
int tmp=ne[nw];
c[tmp]=tot;
if(b[tmp].y==st)
break;
mj+=cj(p[b[tmp].x]-p[st],p[b[tmp].y]-p[st]);
nw=tmp;
}
s1[tot]=mj*mj,s2[tot]=mj;
if(mj<=0)
rt=tot;
}
for(int i=2;i<=cnt;i++)
g[c[i]].push_back(bian(c[i],c[i^1],i));
dfs(rt);
// for(int i=1;i<=cnt;i++)
// cerr<<v[i]<<" ";cerr<<endl;
while(k--)
{
int tot=(read()+ans1)%n+1;
for(int i=1;i<=tot;i++)
a[i]=(read()+ans1)%n+1;
ans1=ans2=0;
a[tot+1]=a[1];
for(int i=1;i<=tot;i++)
{
int nw=f[a[i]][lower_bound(f[a[i]].begin(),f[a[i]].end(),bian(a[i],a[i+1],0))-f[a[i]].begin()].id;
if(v[nw])
{
if(c[nw]==fa[c[nw^1]])
ans1+=s1[c[nw^1]],ans2+=s2[c[nw^1]];
else
ans1-=s1[c[nw]],ans2-=s2[c[nw]];
}
}
if(ans2<0)
ans1*=-1,ans2*=-1;
long long g=gcd(ans1,ans2);
ans1/=g,ans2/=g;
if(ans1&1)
ans2<<=1;
else
ans1>>=1;
printf("%lld %lld\n",ans1,ans2);
}
return 0;
}
bzoj 4541: [Hnoi2016]矿区【平面图转对偶图+生成树】的更多相关文章
- BZOJ 4541: [Hnoi2016]矿区 平面图转对偶图+DFS树
4541: [Hnoi2016]矿区 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 433 Solved: 182[Submit][Status][ ...
- ●BZOJ 4541 [Hnoi2016]矿区
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4541 题解: 平面图的对偶图,dfs树 平面图的对偶图的求法: 把所有双向边拆为两条互为反向 ...
- [BZOJ4541][HNOI2016]矿区(平面图转对偶图)
https://www.cnblogs.com/ljh2000-jump/p/6423399.html #include<cmath> #include<vector> #in ...
- 4541: [Hnoi2016]矿区
学习了一下平面图剖分的姿势,orz cbh 每次只要随便选择一条边,然后不停尽量向左转就行 #include <bits/stdc++.h> #define N 1300000 #defi ...
- BZOJ 4423: [AMPPZ2013]Bytehattan 平面图转对偶图 + 并查集
Description 比特哈顿镇有n*n个格点,形成了一个网格图.一开始整张图是完整的.有k次操作,每次会删掉图中的一条边(u,v),你需要回答在删除这条边之后u和v是否仍然连通. Input 第一 ...
- [HNOI2016]矿区
[HNOI2016]矿区 平面图转对偶图 方法: 1.分成正反两个单向边,每个边属于一个面 2.每个点按照极角序sort出边 3.枚举每一个边,这个边的nxt就是反边的前一个(这样找到的是面的边逆时针 ...
- BZOJ 4541 【HNOI2016】 矿区
题目链接:矿区 这道题去年暑假就想写了,但是一直拖拉,以至于现在才来写这道题.以前一直在刻意回避几何类的题目,但到了现在这个时候,已经没有什么好害怕的了. 正巧今天神犇\(xzy\)讲了这道题,那我就 ...
- LOJ#2052. 「HNOI2016」矿区(平面图转对偶图)
题面 传送门 题解 总算会平面图转对偶图了-- 首先我们把无向边拆成两条单向边,这样的话每条边都属于一个面.然后把以每一个点为起点的边按极角排序,那么对于一条边\((u,v)\),我们在所有以\(v\ ...
- 【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2504 Solved: 1195 Description YT市 ...
随机推荐
- EasyDarwin云存储方案调研:海康萤石云采用的是MPEG-PS打包的方式进行的存储
EasyDarwin开源流媒体服务器项目在直播功能稳定和完善之后,开始涉及服务器端存储与回放功能的调研与开发,当然,这里就要研究一下行业标杆萤石云是怎么来做的,我们通过非常复杂的流程将萤石存储的录像文 ...
- ssh key 生成
1.设置好git的name和email $ git config --global user.name "姓名" $ git config --global user.email ...
- myeclipse查看项目在本地的路径
打开myeclipse编译器,选择项目,右键:选择properties 在这一侧的搜索框中输入:resource Location即是项目的在本地的路径. 亲测好使.
- ABAP OLE常用方法和属性
转自 http://www.cnblogs.com/eric0701/p/5213694.htmlSAP EXCEL OLE常用方法和属性 附加网上找到的比较好的源代码示例一份 1.ole中如何保存和 ...
- !推荐:下载abap 源代码
转自http://blog.sina.com.cn/s/blog_4d1570de0100pvhd.html *@------------------------------------------- ...
- Oracle rac 配置Weblogic数据源时 实例名及URL的选择
Oracle 10G 是 RAC 的,即有两个节点.两个节点 IP及实例名分别为:10.1.43.11 stnic110.1.43.21 stnic2配置数据源时 一直使用的是第一个 URL 及 实例 ...
- codeforces776D
传送门 这题的意思就是原本有一个长度为n的01串,再给出m的长度为n的01串,要求你判定是否可以通过原串与m个串中的某些串xor使得原串到达一个状态.n,m小于1e5. 这题最初我发现不可做,因为这貌 ...
- 动态负载均衡(Nginx+Consul+UpSync)环境搭建
首先 安装好 Consul upsync 然后: 1.配置安装Nginx 需要做配置,包括分组之类的,创建目录,有些插件是需要存放在这些目录的 groupadd nginx useradd -g ng ...
- 在一个form表单中根据不同按钮实现多个action事件
<form id="writeForm" method="post"> <div class="write-btn-tj" ...
- 【概念】SVG(1)
ok,我们讲讲svg 学习前提:懂HTML和基本的XML SVG简介: 1.SVG全称Scable Vector Graphic,可伸缩的矢量图 2.SVG用于定义针对于Web的基于矢量的图形 3.S ...