dyllalala

导航

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+

 

-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('\n');
 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('\n');
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 啊!

 

posted on 2015-01-04 20:37  dyllalala  阅读(226)  评论(0编辑  收藏  举报