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市 ...
随机推荐
- 计算机鼻祖-Donald Knuth(高纳德) 的传奇
李开复说,练内功,不要仅仅花功夫学习各种流行的编程语言和工具,以及一些公司招聘广告上要求的科目.要把数据结构.算法.数据库.操作系统原理.计算机体系结构.计算机网络,离散数学等基础课程学好.最好还是试 ...
- 【BZOJ3197】[Sdoi2013]assassin 树同构+动态规划+KM
[BZOJ3197][Sdoi2013]assassin Description Input Output Sample Input 4 1 2 2 3 3 4 0 0 1 1 1 0 0 0 Sam ...
- CodeSign相关
要让苹果App在真机上跑,需要私钥(PrivateKey),证书(Certificate)和描述文件(Provisioning Profile). (一) 安全基础: 1.非对称加密: 2.Hash码 ...
- ZOJ - 3948 Marjar Cola 【循环】
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3948 题意 用 x 个 瓶身 可以 换 一瓶饮料 用 y 个 瓶 ...
- Non-parseable POM C:\Users\admin\.m2\repository\org\springframework问题解决方案
现象: [INFO] Scanning for projects... [ERROR] [ERROR] Some problems were encountered while processing ...
- Android Weekly Notes Issue #240
Android Weekly Issue #240 January 15th, 2017 Android Weekly Issue #240 Hello, 各位亲, 从本篇笔记开始, 以后并不包含An ...
- Redis缓存服务搭建及实现数据读写 - Eric.Chen
发现博客园中好多大牛在介绍自己的开源项目是很少用到缓存,比如Memcached.Redis.mongodb等,今天得空抽时间把Redis缓存研究了一下,写下来总结一下,跟大家一起分享 一下.由于小弟水 ...
- 深入理解c语言——‘\0’ ,‘0’, “0” ,0之间的区别
看来基础还是很重要的,基础不扎实就难以学好c语言,就别说写出高质量的c语言代码了.今天,我就被这个问题折磨的不行了,哈哈,不过现在终于明白了‘\0’ ,‘0’, “0” 之间的区别了.困惑和快乐与你分 ...
- Android:SQLiteOpenHelper类(SQLlite数据库操作)详细解析
前言 SQLite数据库操作在Android开发中非常常用 今天我将带大家全面了解关于SQLite数据库的操作(增.删.查.改) 目录 1. SQLite数据库介绍 SQLite是Android内置的 ...
- 脚踏实地学C#1-基元类型
基元类型:编译器直接支持的数据类型 基元类型直接映射到FCL类库上,如int 和Int32是等价的,只不过是int是c#提供的,Int32是FCL类库提供的. int只是Int32的别名 using ...