https://loj.ac/problem/2052

题解

平面图转对偶图。。

首先我们转的话需要给所有的平面标号,然后找到每条边看看他们隔开了哪两个平面。

做法就是对每个点维护它的所有排好序的出边,然后对于每一条有序边找到它的一条后继边。

如果一直找下去,就会找到一个平面,依次标号就好了。

我们转好了对偶图,\(dfs\)出对偶图的一颗生成树,然后对于一次询问,它肯定是切出了树上的一些联通块。

所以我们讨论一下每一条边的方向算一下答案就好了。

代码

#include<bits/stdc++.h>
#define N 200009
#define M 1200009
using namespace std;
typedef long long ll;
const double eps=1e-9;
int tot=1,n,m,q,pos[M],rt,b[N],nxt[M],num;
ll s[M],S[M],f[M];
bool ms[M],vis[M];
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();};
return f?-x:x;
}
struct point{
ll x,y;
inline point operator +(const point &b)const{return point{x+b.x,y+b.y};}
inline point operator -(const point &b)const{return point{x-b.x,y-b.y};}
inline ll operator *(const point &b)const{return x*b.y-y*b.x;}
}a[N];
struct edge{
int id,u,v;
double ang;
inline bool operator <(const edge &b)const{
if(fabs(ang-b.ang)>eps)return ang<b.ang;
}
}e[M];
vector<edge>vec[N];
vector<int>ed[M],ps[M];
inline void add(int x,int y){
++tot;e[tot]=edge{tot,x,y,atan2(a[y].y-a[x].y,a[y].x-a[x].x)};
vec[x].push_back(e[tot]);
}
inline void build(){
for(int i=1;i<=n;++i)sort(vec[i].begin(),vec[i].end());
for(int i=2;i<=tot;++i){
int id=e[i].v;
vector<edge>::iterator it=lower_bound(vec[id].begin(),vec[id].end(),e[i^1]);
if(it==vec[id].begin())it=vec[id].end();
--it;nxt[i]=it->id;
}
for(int i=2;i<=tot;++i)if(!pos[i]){
pos[i]=pos[nxt[i]]=++num;
int x=nxt[i];
while(1){
if(e[x].v==e[i].u)break;
s[num]+=(a[e[x].u]-a[e[i].u])*(a[e[x].v]-a[e[i].u]);
x=nxt[x];pos[x]=num;
}
if(s[num]<=0)rt=num,s[num]=0;
}
for(int i=2;i<=tot;++i)ed[pos[i]].push_back(pos[i^1]),ps[pos[i]].push_back(i);
}
void dfs(int u,int fa){
f[u]=fa;
S[u]=s[u]*s[u];s[u]<<=1;vis[u]=1;
for(int i=0;i<ed[u].size();++i){
int v=ed[u][i],tg=ps[u][i];
if(vis[v])continue;
ms[tg]=ms[tg^1]=1;
dfs(v,u);
S[u]+=S[v];s[u]+=s[v];
}
}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
void solve(){
ll ans1=0,ans2=0;
while(q--){
int x=(rd()+ans1)%n+1;
for(int i=1;i<=x;++i)b[i]=(rd()+ans1)%n+1;
ans1=ans2=0;
b[x+1]=b[1];
for(int i=1;i<=x;++i){
int xx=b[i],yy=b[i+1];
// cout<<xx<<" "<<ans1<<" "<<ans2<<" ";
edge z=edge{0,xx,yy,atan2(a[yy].y-a[xx].y,a[yy].x-a[xx].x)};
vector<edge>::iterator it=lower_bound(vec[xx].begin(),vec[xx].end(),z);
int j=it->id;
if(!ms[j])continue;
if(f[pos[j]]==pos[j^1])ans1+=S[pos[j]],ans2+=s[pos[j]];
else ans1-=S[pos[j^1]],ans2-=s[pos[j^1]];
}
ll g=gcd(ans1,ans2);
ans1/=g;ans2/=g;
printf("%lld %lld\n",ans1,ans2);
}
}
int main(){
n=rd();m=rd();q=rd();
int x,y;
for(int i=1;i<=n;++i){
x=rd();y=rd();
a[i]=point{x,y};
}
for(int i=1;i<=m;++i){
x=rd();y=rd();
add(x,y);add(y,x);
}
build();dfs(rt,0);solve();
return 0;
}

「HNOI2016」矿区的更多相关文章

  1. LOJ#2052. 「HNOI2016」矿区(平面图转对偶图)

    题面 传送门 题解 总算会平面图转对偶图了-- 首先我们把无向边拆成两条单向边,这样的话每条边都属于一个面.然后把以每一个点为起点的边按极角排序,那么对于一条边\((u,v)\),我们在所有以\(v\ ...

  2. 【LOJ】#2052. 「HNOI2016」矿区

    题解 之前尝试HNOI2016的时候弃坑的一道,然后给补回来 (为啥我一些计算几何就写得好长,不过我写啥都长orz) 我们尝试给这个平面图分域,好把这个平面图转成对偶图 怎么分呢,我今天也是第一次会 ...

  3. loj2052 「HNOI2016」矿区

    学习一发平面图的姿势--ref #include <algorithm> #include <iostream> #include <cstdio> #includ ...

  4. 「HNOI2016」数据结构大毒瘤

    真是 \(6\) 道数据结构毒瘤... 开始口胡各种做法... 「HNOI2016」网络 整体二分+树状数组. 开始想了一个大常数 \(O(n\log^2 n)\) 做法,然后就被卡掉了... 发现直 ...

  5. 「HNOI2016」树 解题报告

    「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...

  6. 「HNOI2016」序列 解题报告

    「HNOI2016」序列 有一些高妙的做法,懒得看 考虑莫队,考虑莫队咋移动区间 然后你在区间内部找一个最小值的位置,假设现在从右边加 最小值左边区间显然可以\(O(1)\),最小值右边的区间是断掉的 ...

  7. 「HNOI2016」网络 解题报告

    「HNOI2016」网络 我有一个绝妙的可持久化树套树思路,可惜的是,它的空间是\(n\log^2 n\)的... 注意到对一个询问,我们可以二分答案 然后统计经过这个点大于当前答案的路径条数,如果这 ...

  8. 「HNOI2016」最小公倍数 解题报告

    「HNOI2016」最小公倍数 考虑暴力,对每个询问,处理出\(\le a,\le b\)的与询问点在一起的联通块,然后判断是否是一个联通块,且联通块\(a,b\)最大值是否满足要求. 然后很显然需要 ...

  9. loj #2051. 「HNOI2016」序列

    #2051. 「HNOI2016」序列 题目描述 给定长度为 n nn 的序列:a1,a2,⋯,an a_1, a_2, \cdots , a_na​1​​,a​2​​,⋯,a​n​​,记为 a[1: ...

随机推荐

  1. java基础/java调用shell命令和脚本

    一.项目需求: 从某一机构获取证书,证书机构提供小工具,执行.sh脚本即可启动服务,本地调用该服务即可获取证书. 问题:linux服务器启动该服务,不能关闭.一旦关闭,服务即停止. 解决方案:java ...

  2. Java第三周课程总结&实验报告一

    第三周课程总结 1.关于面向对象的一些具体内容,明白了类与对象以及Java的封装性和构造方法以及对对象匿名的相关知识. 2.this关键字,它是表示类的成员属性(变量),使用this构造方法时必须放在 ...

  3. LINUX “软链接”和“硬链接”的区别

    今天在知乎上看到一篇十分有趣的问题: 如何评价微软高级工程师痴迷于soft link这一linux常见概念? 虽然又是知名撕逼王曾某的撕逼帖,但是我还是想就题目中链接的问题简单地讲讲. 什么是链接? ...

  4. GraphQL入门有这一篇就足够了

    GraphQL入门有这一篇就足够了:https://blog.csdn.net/qq_41882147/article/details/82966783 版权声明:本文为博主原创文章,遵循 CC 4. ...

  5. 程序员听到bug后的N种反应…

    程序员的世界里, 不止有代码, 还有bug,bug,bug- 当出现bug时, 程序员们的反应是怎样的呢? 作者:苏小喵,来源:小花小画(微信号:hua-little) - END - 推荐阅读: 1 ...

  6. Django @csrf_exempt不适用于基于通用视图的类(Django @csrf_exempt does not work on generic view based class)

    class ChromeLoginView(View): def get(self, request): return JsonResponse({'status': request.user.is_ ...

  7. 排列perm HYSBZ - 1072(状压dp/暴力)

    Description 给一个数字串s和正整数d, 统计s有多少种不同的排列能被d整除(可以有前导0).例如123434有90种排列能被2整除,其中末位为2的有30种,末位为4的有60种. Input ...

  8. Spring boot项目集成Neo4j

    第一步,创建Springboot工程 使用Eclipse 创建Maven项目,并修改pom.xml文件为: <?xml version="1.0" encoding=&quo ...

  9. php strpos() 函数介绍与使用方法详解

    本文主要和大家介绍PHP中mb_strpos的使用技巧,通过使用语法以及实例给大家详细分析了用法,需要的朋友参考学习下.希望能帮助到大家.mb_strpos(PHP 4 >= 4.0.6, PH ...

  10. ELK-全文检索技术-elasticsearch集群及sde_restful

    1       搭建ES集群 集群的说明 我们计划集群名称为:leyou-elastic,部署3个elasticsearch节点,分别是: node-01:http端口9201,TCP端口9301 n ...