[BZOJ4541][HNOI2016]矿区(平面图转对偶图)
https://www.cnblogs.com/ljh2000-jump/p/6423399.html
1 #include<cmath> 2 #include<vector> 3 #include<cstdio> 4 #include<algorithm> 5 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 6 typedef long long ll; 7 using namespace std; 8 9 const int N=1200010; 10 int n,m,Q,x,y,d,cnt=1,nxt[N],tot,rt,bel[N],fa[N],ask[N]; 11 bool vis[N],in[N]; 12 ll s[N],sp[N],fz,fm; 13 14 struct P{ int x,y; }p[N]; 15 P operator -(const P &a,const P &b){ return (P){a.x-b.x,a.y-b.y}; } 16 ll operator *(const P &a,const P &b){ return 1ll*a.x*b.y-1ll*b.x*a.y; } 17 18 struct E{ 19 int u,v,id; double sl; 20 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)){} 21 }e[N]; 22 bool operator <(const E &a,const E &b){ return a.sl<b.sl; } 23 vector<E>w[N],tr[N]; 24 void add(int u,int v){ cnt++; e[cnt]=(E){u,v,cnt}; w[u].push_back(e[cnt]); } 25 26 ll gcd(ll a,ll b){ return b ? gcd(b,a%b) : a; } 27 28 int find(int x,E b){ 29 int l=0,r=w[x].size()-1; 30 while (l<r){ 31 int mid=(l+r+1)>>1; 32 if (b<w[x][mid]) r=mid-1; else l=mid; 33 } 34 return l; 35 } 36 37 void dfs(int x){ 38 vis[x]=1; sp[x]=s[x]*s[x]; s[x]<<=1; int ed=tr[x].size()-1; 39 rep(i,0,ed){ 40 int v=tr[x][i].v; if (vis[v]) continue; 41 fa[v]=x; in[tr[x][i].id]=in[tr[x][i].id^1]=1; 42 dfs(v); s[x]+=s[v]; sp[x]+=sp[v]; 43 } 44 } 45 46 int main(){ 47 freopen("bzoj4541.in","r",stdin); 48 freopen("bzoj4541.out","w",stdout); 49 scanf("%d%d%d",&n,&m,&Q); 50 rep(i,1,n) scanf("%d%d",&x,&y),p[i]=(P){x,y}; 51 rep(i,1,m) scanf("%d%d",&x,&y),add(x,y),add(y,x); 52 rep(i,1,n) sort(w[i].begin(),w[i].end()); 53 rep(i,2,cnt){ 54 int ne=find(e[i].v,e[i^1])-1; 55 if (ne==-1) ne=w[e[i].v].size()-1; 56 nxt[i]=w[e[i].v][ne].id; 57 } 58 rep(i,2,cnt) if (!bel[i]){ 59 bel[i]=bel[nxt[i]]=++tot; 60 for (int x=nxt[i]; e[x].v!=e[i].u; x=nxt[x],bel[x]=tot) 61 s[tot]+=(p[e[x].u]-p[e[i].u])*(p[e[x].v]-p[e[i].u]); 62 if (s[tot]<=0) rt=tot; 63 } 64 rep(i,2,cnt) tr[bel[i]].push_back(E(bel[i],bel[i^1],i)); 65 dfs(rt); 66 while (Q--){ 67 scanf("%d",&d); d=(d+fz)%n+1; 68 rep(i,1,d) scanf("%d",&ask[i]),ask[i]=(ask[i]+fz)%n+1; 69 ask[d+1]=ask[1]; fz=fm=0; 70 rep(i,1,d){ 71 int x=w[ask[i]][find(ask[i],E(ask[i],ask[i+1],0))].id; 72 if (!in[x]) continue; 73 if (fa[bel[x]]==bel[x^1]) fm+=s[bel[x]],fz+=sp[bel[x]]; 74 else fm-=s[bel[x^1]],fz-=sp[bel[x^1]]; 75 } 76 ll d=gcd(fz,fm); fz/=d; fm/=d; printf("%lld %lld\n",fz,fm); 77 } 78 return 0; 79 }