【JZOJ 3738】理想城市

来源:互联网 发布:手机安装电脑软件 编辑:程序博客网 时间:2024/04/30 10:14

Description

这里写图片描述
这里写图片描述

Solution

看到是网格上求距离,考虑一下把横竖分开来求,
注意:题目保证两两点的最短路都是唯一的。

先统计竖着总共走了多少步,把每一段连续的横着划分,使得图由很多个宽度为1的矩形组成,
把两两相连的矩形连边,发现是一棵树,树上的每个点中都包含了原图中的一些点,
那么,原图中点x,y竖着走的距离就是划分后x,y所在的矩形x,y这两个点在树上的距离;
用树形DP即可。

现在,竖着走的问题解决了,横着走也一样。

复杂度:O(n)

Code

#include <iostream>#include <cstdio>#include <cstdlib>#define fo(i,a,b)  for(int i=a;i<=b;i++)#define efo(i,q)  for(int i=A[q];i;i=B1[i][0])#define YS(x,y) ((LL)(x)*1000000+(y))using namespace std;typedef long long LL;const int N=100500,M=250317,mo=1e9;int read(int &n){    char ch=' ';int q=0,w=1;    for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());    if(ch=='-')w=-1,ch=getchar();    for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;}int m,n,m1;LL Hx[M][2];int B[N][4],B1[N*2][2],A[N],B0;int FX[4][2]={{-1,0},{1,0},{0,-1},{0,1}};bool z[N];int si[N];int HX(int x,int y){       LL q=YS(x,y);    int i=q%M;    while(Hx[i][0]&&Hx[i][1]!=q)i=(i+1)%M;    return i;}void link(int q,int w){    B1[++B0][0]=A[q],A[q]=B0,B1[B0][1]=w;}int dfsf1(int q){    int t=++m1;    si[t]=-1;    for(int i=q;i;i=B[i][2])z[i]=1,si[t]++;    for(int i=q;i;i=B[i][3])z[i]=1,si[t]++;    for(int i=q;i;i=B[i][2])fo(j,0,1)if(!z[B[i][j]])link(t,dfsf1(B[i][j]));    for(int i=q;i;i=B[i][3])fo(j,0,1)if(!z[B[i][j]])link(t,dfsf1(B[i][j]));    return t;}int dfsf2(int q){    int t=++m1;    si[t]=-1;    for(int i=q;i;i=B[i][0])z[i]=0,si[t]++;    for(int i=q;i;i=B[i][1])z[i]=0,si[t]++;    for(int i=q;i;i=B[i][0])fo(j,2,3)if(z[B[i][j]])link(t,dfsf2(B[i][j]));    for(int i=q;i;i=B[i][1])fo(j,2,3)if(z[B[i][j]])link(t,dfsf2(B[i][j]));    return t;}LL f[N],f1[N],ans;void dfs(int q){    f[q]=f1[q]=0;    efo(i,q)    {        dfs(B1[i][1]);        ans=(ans+f[q]*f1[B1[i][1]]+f[B1[i][1]]*f1[q])%mo;        f[q]=(f[q]+f[B1[i][1]])%mo,f1[q]+=f1[B1[i][1]];    }    ans=(ans+si[q]*f[q])%mo;    f1[q]+=si[q];    f[q]+=f1[q];}int main(){    freopen("city.in","r",stdin);    freopen("city.out","w",stdout);    int q,w;    read(n);    fo(i,1,n)    {        read(q),read(w);        int t=HX(q,w);        Hx[t][0]=i;        Hx[t][1]=YS(q,w);        fo(j,0,3)        {            int t=Hx[HX(q+FX[j][0],w+FX[j][1])][0];            if(!t)continue;            B[i][j]=t;            if(j<2)B[t][(j+1)%2]=i;                else B[t][(j-1)%2+2]=i;        }    }    z[0]=1;m1=0;    dfsf1(1);    dfs(1);    z[0]=m1=B0=0;    fo(i,0,n)A[i]=0;    dfsf2(1);    dfs(1);    printf("%lld\n",ans);    return 0;}
0 0