zoukankan      html  css  js  c++  java
  • 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('
    ');
     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('
    ');
     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('
    ');
     89             }
     90             else
     91             {
     92                 putint(ans2.x), putchar(' ');
     93                 putint(ans2.y), putchar('
    ');
     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+

    -Distance

    一道我认为做法极其诡异的题目,很容易想到若令 g[i] 表示 i 有几个质因子,则 d[x, y]=g[x]+g[y]-2*g[gcd(x, y)]

    然后我就想不下去了……一看题解,居然是枚举 x 的因数!然后暴力搞搞就出来了,细节部分要仔细推敲。

    还有 n 的质因子数应该是 O(log2n) 所以 n 的因子数最差情况似乎是 O(n) 级别的?也只能说是数据弱了~

      1 #include <cstdio>
      2 #include <cstring>
      3 const int sizeOfNumber=100001;
      4 const int sizeOfSieve=1000001;
      5 const int inf=0x7F7F7F7F;
      6 
      7 inline int getint();
      8 inline void putint(int);
      9 
     10 bool b[sizeOfSieve];
     11 int m, p[sizeOfNumber];
     12 int e[sizeOfSieve], c[sizeOfSieve];
     13 inline void sieve();
     14 
     15 struct node {int v, t; inline node(int=0, int=0);};
     16 
     17 int n, l;
     18 int ansv, anst;
     19 int a[sizeOfNumber];
     20 node s[sizeOfNumber];
     21 int v1[sizeOfSieve], v2[sizeOfSieve];
     22 int t1[sizeOfSieve], t2[sizeOfSieve];
     23 void search(int, int);
     24 void query(int, int);
     25 
     26 int main()
     27 {
     28     sieve();
     29 
     30     n=getint();
     31     for (int i=1;i<=n;i++)
     32         a[i]=getint();
     33 
     34     memset(v1, 0x7F, sizeof(v1));
     35     memset(v2, 0x7F, sizeof(v2));
     36     for (int i=1;i<=n;i++)
     37     {
     38         int t=a[i];
     39 
     40         s[0]=node(0, 0);
     41         for (l=0;t>1;t/=e[t])
     42         {
     43             if (e[t]!=s[l].v)
     44                 s[++l]=node(e[t], 1);
     45             else
     46                 s[l].t++;
     47         }
     48         s[0]=node(a[i], i);
     49         search(1, 1);
     50     }
     51     for (int i=1;i<=n;i++)
     52     {
     53         int t=a[i];
     54 
     55         s[0]=node(0, 0);
     56         for (l=0;t>1;t/=e[t])
     57         {
     58             if (e[t]!=s[l].v || !l)
     59                 s[++l]=node(e[t], 1);
     60             else
     61                 s[l].t++;
     62         }
     63         s[0]=node(a[i], i);
     64 
     65         ansv=anst=inf;
     66         query(1, 1);
     67         putint(anst);
     68     }
     69 
     70     return 0;
     71 }
     72 
     73 inline int getint()
     74 {
     75     register int num=0;
     76     register char ch;
     77     do ch=getchar(); while (ch<'0' || ch>'9');
     78     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
     79     return num;
     80 }
     81 inline void putint(int num)
     82 {
     83     char stack[11];
     84     register int top=0;
     85     if (num==0) stack[top=1]='0';
     86     for ( ;num;num/=10) stack[++top]=num%10+'0';
     87     for ( ;top;top--) putchar(stack[top]);
     88     putchar('
    ');
     89 }
     90 
     91 inline void sieve()
     92 {
     93     for (int i=2;i<sizeOfSieve;i++)
     94     {
     95         if (!b[i])
     96         {
     97             p[m++]=i;
     98             e[i]=i; c[i]=1;
     99         }
    100 
    101         for (int j=0;j<m;j++)
    102         {
    103             if (i*p[j]>=sizeOfSieve) break;
    104             b[i*p[j]]=true;
    105             e[i*p[j]]=p[j]; c[i*p[j]]=c[i]+1;
    106             if (e[i]==p[j]) break;
    107         }
    108     }
    109 }
    110 
    111 inline node::node(int _v, int _t)
    112 {
    113     v=_v, t=_t;
    114 }
    115 
    116 void search(int v, int t)
    117 {
    118     if (t>l)
    119     {
    120         int g=c[s[0].v]-(c[v]<<1);
    121         if (g<v1[v])
    122         {
    123             v2[v]=v1[v], t2[v]=t1[v];
    124             v1[v]=g, t1[v]=s[0].t;
    125         }
    126         else if (g<v2[v])
    127             v2[v]=g, t2[v]=s[0].t;
    128     }
    129     else
    130     {
    131         for (int i=0, j=1;i<=s[t].t;i++, j=j*s[t].v)
    132             search(v*j, t+1);
    133     }
    134 }
    135 void query(int v, int t)
    136 {
    137     if (t>l)
    138     {
    139         if (s[0].t!=t1[v])
    140         {
    141             if (v1[v]<ansv || (v1[v]==ansv && t1[v]<anst))
    142                 ansv=v1[v], anst=t1[v];
    143         }
    144         else if (v2[v]<ansv || (v2[v]==ansv && t2[v]<anst))
    145                 ansv=v2[v], anst=t2[v];
    146     }
    147     else
    148     {
    149         for (int i=0, j=1;i<=s[t].t;i++, j=j*s[t].v)
    150             query(v*j, t+1);
    151     }
    152 }
    调了半天 T_T

    -Letters

    这道题目应该还是比较简单的吧,一眼就看出是求逆序对数,利用第一个字符串给第二个字符串标号(是字母对应字母的标号,开 26 个队列即可)

    本质其实和直接算逆序对数是一样的,只不过这道题可以看作是对 “顺序” 重新下了一个定义罢了~

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 typedef long long LL;
     5 const int sizeOfString=1000001;
     6 
     7 inline int getint();
     8 inline int getstr(char * );
     9 inline void putint(LL);
    10 
    11 int C[sizeOfString];
    12 inline int lowbit(int);
    13 inline void update(int);
    14 inline int query(int);
    15 
    16 int N;
    17 char J[sizeOfString], M[sizeOfString];
    18 std::queue<int> q[26];
    19 int A[sizeOfString];
    20 
    21 int main()
    22 {
    23     LL ans=0;
    24 
    25     N=getint();
    26     getstr(J);
    27     getstr(M);
    28 
    29     for (int i=0;i<N;i++)
    30         q[J[i]-'A'].push(i);
    31     for (int i=0;i<N;i++)
    32     {
    33         A[i]=1+q[M[i]-'A'].front();
    34         q[M[i]-'A'].pop();
    35     }
    36 
    37     for (int i=0;i<N;i++)
    38     {
    39         ans+=query(A[i]);
    40         update(A[i]);
    41     }
    42 
    43     putint(ans);
    44 
    45     return 0;
    46 }
    47 
    48 inline int getint()
    49 {
    50     register int num=0;
    51     register char ch;
    52     do ch=getchar(); while (ch<'0' || ch>'9');
    53     do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
    54     return num;
    55 }
    56 inline int getstr(char * str)
    57 {
    58     register int len=0;
    59     register char ch;
    60     do ch=getchar(); while (ch<'A' || ch>'Z');
    61     do str[len++]=ch, ch=getchar(); while (ch>='A' && ch<='Z');
    62     return len;
    63 }
    64 inline void putint(LL num)
    65 {
    66     char stack[22];
    67     register int top=0;
    68     if (num==0) stack[top=1]='0';
    69     for ( ;num;num/=10) stack[++top]=num%10+'0';
    70     for ( ;top;top--) putchar(stack[top]);
    71     putchar('
    ');
    72 }
    73 
    74 inline int lowbit(int i)
    75 {
    76     return i & -i;
    77 }
    78 inline void update(int i)
    79 {
    80     for ( ;i;i-=lowbit(i))
    81         C[i]++;
    82 }
    83 inline int query(int i)
    84 {
    85     int ret=0;
    86     for ( ;i<=N;i+=lowbit(i))
    87         ret+=C[i];
    88     return ret;
    89 }
    一 A 啊!久违的一 A 啊!
  • 相关阅读:
    简单cpu处理器
    用4bit的counter看同步复位与异步复位
    135实例——add_4
    int_float_double数据类型的存储格式。
    C#基础精华----枚举
    MSSQLServer基础07(事务,存储过程,分页的存储过程,触发器)
    MSSQLServer基础06(变量,case,选择语句)
    SqlHelper类
    ADO.NET基础02(语句参数化,配置文件,DataSet与DataTable)
    ADO.NET基础01(ADO.NET组成,数据库的方式,SqlCommand,SqlDataReader)
  • 原文地址:https://www.cnblogs.com/dyllalala/p/4202224.html
Copyright © 2011-2022 走看看