首页 > 代码库 > POI2012

POI2012

现在才开始写 POI 是不是太弱了?

-Rendezvous

怎么说呢,我发现我的代码好长啊~长啊~长啊~长长长长长长长长长长长长长长长长长长长长长长啊~

大概就是在一个内向树上搞一个类似 lca 的东西,想想内向树估计就可以搞出来了吧……

技术分享
  1 #include <cstdio>  2 const int sizeOfPoint=500005;  3 const int sizeOfEdge=500005;  4   5 inline int lg(int);  6 inline int min(int, int);  7 inline int max(int, int);  8 inline void swap(int & , int & );  9 inline int getint(); 10 inline void putint(int); 11  12 struct edge {int point; edge * next;}; 13 edge memory[sizeOfEdge], * port=memory; 14 inline edge * newedge(int, edge * ); 15  16 struct node {int x, y; inline node(int=0, int=0);}; 17 inline bool operator < (node, node); 18  19 int n, m, k; 20 int p[sizeOfPoint]; 21 edge * e[sizeOfPoint]; 22 int a[32][sizeOfPoint]; 23 int g[sizeOfPoint], s[sizeOfPoint]; 24 int f[sizeOfPoint], d[sizeOfPoint]; 25 int l[sizeOfPoint]; 26 bool v[sizeOfPoint], b[sizeOfPoint]; 27 inline void bfs(int); 28 inline int lca(int, int); 29  30 int main() 31 { 32     n=getint(), k=getint(); 33     for (int i=1;i<=n;i++) 34     { 35         p[i]=getint(); 36         e[p[i]]=newedge(i, e[p[i]]); 37     } 38  39     for (int i=1;i<=n;i++) if (!v[i]) 40     { 41         int u=i; 42         for ( ;!b[u];u=p[u]) b[u]=true; 43  44         ++m; 45         for (int j=1;!l[u];j++, u=p[u]) 46         { 47             g[u]=m; 48             s[m]++; 49             l[u]=j; 50             bfs(u); 51         } 52     } 53  54     for (int i=1;i<=k;i++) 55     { 56         int a=getint(), b=getint(); 57  58         if (g[f[a]]!=g[f[b]]) 59         { 60             putint(-1), putchar( ); 61             putint(-1), putchar(\n); 62         } 63         else if (f[a]==f[b]) 64         { 65             int c=lca(a, b); 66             putint(d[a]-d[c]), putchar( ); 67             putint(d[b]-d[c]), putchar(\n); 68         } 69         else 70         { 71             int o=s[g[f[a]]]; 72             node ans1=node(d[a], d[b]), ans2=node(d[a], d[b]); 73  74             if (l[f[a]]<l[f[b]]) 75             { 76                 ans1.x+=l[f[b]]-l[f[a]]; 77                 ans2.y+=o-(l[f[b]]-l[f[a]]); 78             } 79             else 80             { 81                 ans1.x+=o-(l[f[a]]-l[f[b]]); 82                 ans2.y+=l[f[a]]-l[f[b]]; 83             } 84  85             if (ans1<ans2) 86             { 87                 putint(ans1.x), putchar( ); 88                 putint(ans1.y), putchar(\n); 89             } 90             else 91             { 92                 putint(ans2.x), putchar( ); 93                 putint(ans2.y), putchar(\n); 94             } 95         } 96     } 97  98     return 0; 99 }100 101 inline int lg(int x)102 {103     return 31-__builtin_clz(x);104 }105 inline int min(int x, int y)106 {107     return x<y?x:y;108 }109 inline int max(int x, int y)110 {111     return x>y?x:y;112 }113 inline void swap(int & x, int & y)114 {115     int t=x; x=y; y=t;116 }117 inline int getint()118 {119     register int num=0;120     register char ch;121     do ch=getchar(); while (ch<0 || ch>9);122     do num=num*10+ch-0, ch=getchar(); while (ch>=0 && ch<=9);123     return num;124 }125 inline void putint(int num)126 {127     char stack[11];128     register int top=0;129     if (num==0) stack[top=1]=0;130     if (num<0) putchar(-), num=-num;131     for ( ;num;num/=10) stack[++top]=num%10+0;132     for ( ;top;top--) putchar(stack[top]);133 }134 135 inline edge * newedge(int point, edge * next)136 {137     edge * ret=port++;138     ret->point=point; ret->next=next;139     return ret;140 }141 142 inline node::node(int _x, int _y)143 {144     x=_x;145     y=_y;146 }147 inline bool operator < (node a, node b)148 {149     if (max(a.x, a.y)<max(b.x, b.y)) return true;150     if (max(a.x, a.y)>max(b.x, b.y)) return false;151     if (min(a.x, a.y)<min(b.x, b.y)) return true;152     if (min(a.x, a.y)>min(b.x, b.y)) return false;153     return a.y<b.y;154 }155 156 inline void bfs(int root)157 {158     static int q[sizeOfPoint];159     int s=0, t=0;160     d[root]=0;161     f[root]=root;162 163     for (q[t++]=root;s<t;s++)164     {165         int u=q[s];166         v[u]=true;167         if (d[u]>1)168         {169             int lim=lg(d[u]);170             for (int i=1;i<=lim;i++)171                 a[i][u]=a[i-1][a[i-1][u]];172         }173 174         for (edge * i=e[u];i;i=i->next) if (i->point!=p[u] && !l[i->point])175         {176             d[i->point]=d[u]+1;177             f[i->point]=root;178             a[0][i->point]=u;179             q[t++]=i->point;180         }181     }182 }183 inline int lca(int u, int v)184 {185     int dist;186     if (d[u]<d[v]) swap(u, v);187     while ((dist=d[u]-d[v])) u=a[__builtin_ctz(dist)][u];188     if (u==v) return u;189     for (int i=31;i>=0;i--)190         if (a[i][u]!=a[i][v])191             u=a[i][u],192             v=a[i][v];193     return a[0][u];194 }
LEN:190+

 

POI2012