4541: [Hnoi2016]矿区

时间:2022-09-24 13:58:35

学习了一下平面图剖分的姿势,orz cbh

每次只要随便选择一条边,然后不停尽量向左转就行

#include <bits/stdc++.h>
#define N 1300000
#define M 5000013
#define LL long long
#define pb push_back
using namespace std;
LL n, m, k;
struct point
{
LL x, y;
} S[N];
vector <LL> bi[N];
vector <LL> re[N], vis[N], s1[N], s2[N];
vector <LL> bt[N], ca[N], cb[N];
LL tot_are;
LL siz[N], sum1[N], sum2[N], tot[N];
LL nwc;
LL comp(LL a, LL b)
{
return atan2(S[a].y - S[nwc].y, S[a].x - S[nwc].x) > atan2(S[b].y - S[nwc].y, S[b].x - S[nwc].x);
}
LL getsiz(point a, point b, point c)
{
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
} namespace addr
{
LL hs[M]; LL dt[M];
LL get(LL a, LL b)
{
return 1ll * a * + b;
}
LL & find(LL a, LL b)
{
LL p = get(a, b); LL q = p % M;
while (hs[q] && hs[q] != p) q = (q + ) % M;
hs[q] = p; return dt[q];
}
}
LL tvis[N], fa[N];
void dfs(LL t)
{
//cout << t << "\n"; tvis[t] = ;
sum1[t] = siz[t] * siz[t];
sum2[t] = siz[t] * ;
for (LL i = ; i < bt[t].size(); ++ i)
if (!tvis[bt[t][i]])
{
dfs(bt[t][i]); fa[bt[t][i]] = t;
sum1[t] += sum1[bt[t][i]];
sum2[t] += sum2[bt[t][i]];
s1[ca[t][i]][addr :: find(ca[t][i], cb[t][i])] = sum1[bt[t][i]];
s2[ca[t][i]][addr :: find(ca[t][i], cb[t][i])] = sum2[bt[t][i]];
s1[cb[t][i]][addr :: find(cb[t][i], ca[t][i])] = -sum1[bt[t][i]];
s2[cb[t][i]][addr :: find(cb[t][i], ca[t][i])] = -sum2[bt[t][i]];
}
}
LL read()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
LL c = ;
int main()
{
//freopen("mine2.in", "r", stdin);
n = read(); m = read(); k = read();
for (LL i = ; i <= n; ++ i) S[i].x = read(), S[i].y = read();
for (LL i = ; i <= m; ++ i)
{
LL a, b;
a = read(); b = read();
bi[a].push_back(b);
bi[b].push_back(a);
}
for (LL i = ; i <= n; ++ i) re[i].resize(bi[i].size()), s1[i] = s2[i] = vis[i] = re[i];
for (LL i = ; i <= n; ++ i) nwc = i, sort(bi[i].begin(), bi[i].end(), comp);
for (LL i = ; i <= n; ++ i)
for (LL j = ; j < bi[i].size(); ++ j)
addr :: find(i, bi[i][j]) = j;
for (LL i = ; i <= n; ++ i)
for (LL j = ; j < bi[i].size(); ++ j)
re[i][j] = addr :: find(bi[i][j], i); for (LL i = ; i <= n; ++ i)
for (LL j = ; j < bi[i].size(); ++ j)
if (!vis[i][j])
{
tot_are ++;
for (LL k = i, p = j; !vis[k][p]; )
{
siz[tot_are] += getsiz(S[i], S[k], S[bi[k][p]]);
vis[k][p] = tot_are;
LL np = (re[k][p] + ) % bi[bi[k][p]].size();
k = bi[k][p];
p = np;
}
if (siz[tot_are] < ) c = tot_are;
}
for (LL i = ; i <= n; ++ i)
for (LL j = ; j < bi[i].size(); ++ j)
bt[vis[i][j]].push_back(vis[bi[i][j]][re[i][j]]),
ca[vis[i][j]].push_back(i),
cb[vis[i][j]].push_back(bi[i][j]);
dfs(c);
for (LL i = , last = ; i <= k; ++ i)
{
LL d, ns1 = , ns2 = ;
d = read(); d = (d + last) % n + ;
LL fs, ls, nw;
fs = read(); fs = (fs + last) % n + ; ls = fs;
for (LL j = ; j <= d; ++ j, ls = nw)
{
nw = read(); nw = (nw + last) % n + ;
ns1 += s1[ls][addr :: find(ls, nw)];
ns2 += s2[ls][addr :: find(ls, nw)];
}
ns1 += s1[ls][addr :: find(ls, fs)];
ns2 += s2[ls][addr :: find(ls, fs)];
LL g = __gcd(ns1, ns2);
cout << ns1 / g << " " << ns2 / g << "\n";
last = ns1 / g;
}
}

放在class里的东西还会爆栈QAQ,以后不敢用了

4541: [Hnoi2016]矿区的更多相关文章

  1. BZOJ 4541&colon; &lbrack;Hnoi2016&rsqb;矿区 平面图转对偶图&plus;DFS树

    4541: [Hnoi2016]矿区 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 433  Solved: 182[Submit][Status][ ...

  2. ●BZOJ 4541 &lbrack;Hnoi2016&rsqb;矿区

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4541 题解: 平面图的对偶图,dfs树 平面图的对偶图的求法: 把所有双向边拆为两条互为反向 ...

  3. bzoj 4541&colon; &lbrack;Hnoi2016&rsqb;矿区【平面图转对偶图&plus;生成树】

    首先平面图转对偶图,大概思路是每条边存正反,每个点存出边按极角排序,然后找每条边在它到达点的出边中极角排序的下一个,这样一定是这条边所属最小多边形的临边,然后根据next边找出所有多边形,用三角剖分计 ...

  4. &lbrack;HNOI2016&rsqb;矿区

    [HNOI2016]矿区 平面图转对偶图 方法: 1.分成正反两个单向边,每个边属于一个面 2.每个点按照极角序sort出边 3.枚举每一个边,这个边的nxt就是反边的前一个(这样找到的是面的边逆时针 ...

  5. 【LG3249】&lbrack;HNOI2016&rsqb;矿区

    [LG3249][HNOI2016]矿区 题面 洛谷 题解 先平面图转对偶图, 建好了对偶图之后随意拿出一个生成树,以无边界的范围为根. 无边界的范围很好求,用叉积算出有向面积时,算出来是负数的就是无 ...

  6. BZOJ4541 &lbrack;Hnoi2016&rsqb;矿区

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. 【bzoj4541】 Hnoi2016—矿区

    http://www.lydsy.com/JudgeOnline/problem.php?id=4541 (题目链接) 题意 给出一个平面图,若干询问,每次询问一个凸多边形内小多边形面积的平方和与面积 ...

  8. BZOJ4541 HNOI2016矿区(平面图转对偶图)

    考虑先将平面图转化为对偶图.具体地,将无向边拆成两条有向边.每次考虑找到包围一个区域的所有边.对当前考虑的边,找到该边的反向边在该边终点的出边集中,按极角序排序的后继,这条后继边也是包围该区域的边.这 ...

  9. &lbrack;BZOJ4541&rsqb;&lbrack;HNOI2016&rsqb;矿区&lpar;平面图转对偶图&rpar;

    https://www.cnblogs.com/ljh2000-jump/p/6423399.html #include<cmath> #include<vector> #in ...

随机推荐

  1. Unity3d游戏场景优化杂谈(3)

    LOD(Level-of-detail)是最常用的游戏优化技术 .如果你的程序可以定制开发应用LOD的模块,当然 是很美好的事情.不过如果没有也没关系,大家可以使用UniLOD这个第三方的LOD插件. ...

  2. iOS中通知中心NSNotificationCenter应用总结

    通知中心(NSNotificationCenter)实际是在程序内部提供了一种广播机制.把接收到的消息,根据内部的消息转发表,将消息转发给需要的对象.这句话其实已经很明显的告诉我们要如何使用通知了.第 ...

  3. sql查询当天数据

    向数据库中添加日期 MS SQL SERVER: NSERT into student(studentid,time1)values('15',getdate()); MY SQLinsert int ...

  4. Node学习笔记 http

    node url querystring 第二个参数指定分隔符 也可以指定三个参数,效果和两个参数类似 不同于querystring,下面是querystringfy的用法 queryescape与e ...

  5. 口试Linq题

    LINQ to SQL与IQueryable 理解IQueryable的最简单方式就是,把它看作一个查询,在执行的时候,将会生成结果序列. LINQ to Object和LINQ to SQL有何区别 ...

  6. 使用指针来实现变长数组(VLA)

    实现代码: #include <cstdio> #include <cstdlib> void usePtoImplementVLA(int SIZE) { scanf(&qu ...

  7. 用Setup Factory7&period;0怎样打包delphi的BDE&quest;

    BDE打包发布实例操作步骤如下: 使用软件:Setup Factory 7.0打包 把C:\Program Files\Common Files\Borland Shared中的所有文件和你的开发的应 ...

  8. OGNL mybatis

    http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其 ...

  9. go&lowbar;gc

    如果想知道当前的内存状态,可以使用: // fmt.Printf("%d\n", runtime.MemStats.Alloc/1024) // 此处代码在 Go 1.5.1下不再 ...

  10. 20155215宣言 实验三 敏捷开发与XP实践 实验报告

    实验内容 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程 2.完成实验.撰写实验报告,实 ...