[BZOJ4541][HNOI2016]矿区(平面图转对偶图)

时间:2023-03-08 17:59:04
[BZOJ4541][HNOI2016]矿区(平面图转对偶图)

https://www.cnblogs.com/ljh2000-jump/p/6423399.html

 #include<cmath>
#include<vector>
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=;
int n,m,Q,x,y,d,cnt=,nxt[N],tot,rt,bel[N],fa[N],ask[N];
bool vis[N],in[N];
ll s[N],sp[N],fz,fm; struct P{ int x,y; }p[N];
P operator -(const P &a,const P &b){ return (P){a.x-b.x,a.y-b.y}; }
ll operator *(const P &a,const P &b){ return 1ll*a.x*b.y-1ll*b.x*a.y; } struct E{
int u,v,id; double sl;
E(){}; E(int a,int b,int i):u(a),v(b),id(i),sl(atan2(p[b].y-p[a].y,p[b].x-p[a].x)){}
}e[N];
bool operator <(const E &a,const E &b){ return a.sl<b.sl; }
vector<E>w[N],tr[N];
void add(int u,int v){ cnt++; e[cnt]=(E){u,v,cnt}; w[u].push_back(e[cnt]); } ll gcd(ll a,ll b){ return b ? gcd(b,a%b) : a; } int find(int x,E b){
int l=,r=w[x].size()-;
while (l<r){
int mid=(l+r+)>>;
if (b<w[x][mid]) r=mid-; else l=mid;
}
return l;
} void dfs(int x){
vis[x]=; sp[x]=s[x]*s[x]; s[x]<<=; int ed=tr[x].size()-;
rep(i,,ed){
int v=tr[x][i].v; if (vis[v]) continue;
fa[v]=x; in[tr[x][i].id]=in[tr[x][i].id^]=;
dfs(v); s[x]+=s[v]; sp[x]+=sp[v];
}
} int main(){
freopen("bzoj4541.in","r",stdin);
freopen("bzoj4541.out","w",stdout);
scanf("%d%d%d",&n,&m,&Q);
rep(i,,n) scanf("%d%d",&x,&y),p[i]=(P){x,y};
rep(i,,m) scanf("%d%d",&x,&y),add(x,y),add(y,x);
rep(i,,n) sort(w[i].begin(),w[i].end());
rep(i,,cnt){
int ne=find(e[i].v,e[i^])-;
if (ne==-) ne=w[e[i].v].size()-;
nxt[i]=w[e[i].v][ne].id;
}
rep(i,,cnt) if (!bel[i]){
bel[i]=bel[nxt[i]]=++tot;
for (int x=nxt[i]; e[x].v!=e[i].u; x=nxt[x],bel[x]=tot)
s[tot]+=(p[e[x].u]-p[e[i].u])*(p[e[x].v]-p[e[i].u]);
if (s[tot]<=) rt=tot;
}
rep(i,,cnt) tr[bel[i]].push_back(E(bel[i],bel[i^],i));
dfs(rt);
while (Q--){
scanf("%d",&d); d=(d+fz)%n+;
rep(i,,d) scanf("%d",&ask[i]),ask[i]=(ask[i]+fz)%n+;
ask[d+]=ask[]; fz=fm=;
rep(i,,d){
int x=w[ask[i]][find(ask[i],E(ask[i],ask[i+],))].id;
if (!in[x]) continue;
if (fa[bel[x]]==bel[x^]) fm+=s[bel[x]],fz+=sp[bel[x]];
else fm-=s[bel[x^]],fz-=sp[bel[x^]];
}
ll d=gcd(fz,fm); fz/=d; fm/=d; printf("%lld %lld\n",fz,fm);
}
return ;
}