第三周 7.24-7.30

7.24

HDU 1402 A * B Problem Plus

抄板。

  1 // HDU 1402 A * B Problem Plus
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <algorithm>
  7 using namespace std;
  8 const int maxn = 5e4 + 10;
  9 int a[maxn], b[maxn], c[maxn<<2];
 10 char s1[maxn], s2[maxn];
 11 
 12 // FFT
 13 const double Pi = acos(-1.0);
 14 
 15 struct complex
 16 {
 17     double r, i;
 18     complex(double r = 0, double i = 0): r(r), i(i) {}
 19     complex operator + (const complex &ot) const
 20     {
 21         return complex(r + ot.r, i + ot.i);
 22     }
 23     complex operator - (const complex &ot) const
 24     {
 25         return complex(r - ot.r, i - ot.i);
 26     }
 27     complex operator * (const complex &ot) const
 28     {
 29         return complex(r * ot.r - i * ot.i, r * ot.i + i * ot.r);
 30     }
 31 } x1[maxn<<2], x2[maxn<<2];
 32 
 33 void change(complex * y, int len)
 34 {
 35     for(int i = 1, j = len >> 1; i < len - 1; i++)
 36     {
 37         if(i < j) swap(y[i], y[j]);
 38         int k = len >> 1;
 39         while(j >= k) j -= k, k >>= 1;
 40         j += k;
 41     }
 42 }
 43 
 44 void FFT(complex * y, int len, int on)
 45 {
 46     change(y, len);
 47     for(int h = 2; h <= len; h <<= 1)
 48     {
 49         complex wn = complex(cos(on * 2 * Pi / h), sin(on * 2 * Pi / h));
 50         for(int j = 0; j < len; j += h)
 51         {
 52             complex w = complex(1, 0);
 53             for(int k = j; k < j + h / 2; k++)
 54             {
 55                 complex u = y[k];
 56                 complex t = y[k+h/2] * w;
 57                 y[k] = u + t;
 58                 y[k+h/2] = u - t;
 59                 w = w * wn;
 60             }
 61         }
 62     }
 63     if(on == -1)
 64     {
 65         for(int i = 0; i < len; i++)
 66         {
 67             y[i].r /= len;
 68         }
 69     }
 70 }
 71 
 72 void cal(int * a, int * b, int * c, int l)
 73 {
 74     int len = 1;
 75     while(len < l * 2) len <<= 1;
 76     for(int i = 0; i < l; i++)
 77     {
 78         x1[i] = complex(a[i], 0);
 79         x2[i] = complex(b[i], 0);
 80     }
 81     for(int i = l; i < len; i++) x1[i] = x2[i] = complex(0, 0);
 82     FFT(x1, len, 1);
 83     FFT(x2, len, 1);
 84     for(int i = 0; i < len; i++) x1[i] = x1[i] * x2[i];
 85     FFT(x1, len, -1);
 86     for(int i = 0; i < len; i++)
 87         c[i] = x1[i].r + 0.5;
 88 }
 89 
 90 int main(void)
 91 {
 92     while(~scanf("%s %s", s1, s2))
 93     {
 94         int l1 = strlen(s1), l2 = strlen(s2);
 95         int l = max(l1, l2);
 96         for(int i = 0; i < l; i++)
 97         {
 98             a[i] = l1 - i - 1 >= 0 ? s1[l1-i-1] - '0' : 0;
 99             b[i] = l2 - i - 1 >= 0 ? s2[l2-i-1] - '0' : 0;
100         }
101 
102         memset(c, 0, sizeof(c));
103         cal(a, b, c, l);
104         for(int i = 0; i < l1 + l2; i++)
105         {
106             c[i+1] += c[i] / 10;
107             c[i] %= 10;
108         }
109 
110         int st = 0;
111         for(int i = l1 + l2; i >= 0; i--)
112         {
113             if(!st && !c[i] && i) continue;
114             st = 1;
115             printf("%d", c[i]);
116         }
117         puts("");
118     }
119     return 0;
120 }
Aguin

 

补套BC。

 

HDU 5747 Aaronson

很好写的水题哟。

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 int main(void)
 6 {
 7     int T;
 8     scanf("%d", &T);
 9     while(T--)
10     {
11         int n, m;
12         scanf("%d %d", &n, &m);
13         int ans = 0;
14         while(n && m)
15         {
16             if(n % 2) ans++;
17             n /= 2, m--;
18         }
19         ans += n;
20         printf("%d\n", ans);
21     }
22     return 0;
23 }
Aguin

 

HDU 5448 Bellovin

看sample可能会猜出就是答案dp数组。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 const int maxn = 1e5 + 10;
 7 int f[maxn];
 8 
 9 struct node
10 {
11     int p, a;
12     friend bool operator < (node A, node B)
13     {
14         if(A.a != B.a) return A.a < B.a;
15         return A.p > B.p;
16     }
17 } num[maxn];
18 
19 // BIT
20 int c[maxn];
21 int lowbit(int s)
22 {
23     return s & (-s);
24 }
25 void modify(int i, int x)
26 {
27     while(i < maxn) c[i] = max(c[i], x), i += lowbit(i);
28     return;
29 }
30 int query(int i)
31 {
32     int ret = 0;
33     while(i > 0) ret = max(ret, c[i]), i -= lowbit(i);
34     return ret;
35 }
36 
37 int main(void)
38 {
39     int T;
40     scanf("%d", &T);
41     while(T--)
42     {
43         int N;
44         scanf("%d", &N);
45         for(int i = 1; i <= N; i++)
46         {
47             scanf("%d", &num[i].a);
48             num[i].p = i;
49         }
50         sort(num + 1, num + 1 + N);
51 
52         memset(c, 0, sizeof(c));
53         for(int i = 1; i <= N; i++)
54         {
55             int p = num[i].p;
56             f[p] = query(p) + 1;
57             modify(p, f[p]);
58         }
59 
60         for(int i = 1; i < N; i++) printf("%d ", f[i]);
61         printf("%d\n", f[N]);
62     }
63     return 0;
64 }
Aguin

 

HDU 5449 Colmerauer

因为每个鞍点的贡献是它的值乘上所在矩阵的覆盖面积,

先用n2预处理了f[l][r]表示一条线段左边延伸l,右边延伸r的所有子线段和。

再用单调栈四个方向处理每个数在l,r,u,d范围内是鞍点。

这样一来f[l][r]乘f[u][d]就是所有子矩阵的面积和拉。

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 typedef unsigned int ui;
 5 int l[1111][1111], r[1111][1111];
 6 int u[1111][1111], d[1111][1111];
 7 ui M[1111][1111], f[1111][1111];
 8 
 9 int main(void)
10 {
11     for(ui i = 0; i <= 1000; i++)
12     {
13         f[i][0] = i ? f[i-1][0] + i + 1 : 1;
14         for(ui j = 1; j <= 1000; j++)
15             f[i][j] = f[i][j-1] + (i + 1) * (j + 1) + i * (i + 1) / 2;
16     }
17 
18     int T;
19     scanf("%d", &T);
20     while(T--)
21     {
22         int n, m;
23         scanf("%d %d", &n, &m);
24         for(int i = 1; i <= n; i++)
25             for(int j = 1; j <= m; j++)
26                 scanf("%u", &M[i][j]);
27 
28         // l
29         for(int i = 1; i <= n; i++)
30         {
31             int st[1111], p = 0;
32             for(int j = 1; j <= m; j++)
33             {
34                 while(p && M[i][st[p]] > M[i][j]) p--;
35                 l[i][j] = p ? (j - st[p] - 1) : (j - 1);
36                 st[++p] = j;
37             }
38         }
39 
40         // r
41         for(int i = 1; i <= n; i++)
42         {
43             int st[1111], p = 0;
44             for(int j = m; j >= 1; j--)
45             {
46                 while(p && M[i][st[p]] > M[i][j]) p--;
47                 r[i][j] = p ? (st[p] - j - 1) : (m - j);
48                 st[++p] = j;
49             }
50         }
51 
52         // u
53         for(int j = 1; j <= m; j++)
54         {
55             int st[1111], p = 0;
56             for(int i = 1; i <= n; i++)
57             {
58                 while(p && M[st[p]][j] < M[i][j]) p--;
59                 u[i][j] = p ? (i - st[p] - 1) : (i - 1);
60                 st[++p] = i;
61             }
62         }
63 
64         // d
65         for(int j = 1; j <= m; j++)
66         {
67             int st[1111], p = 0;
68             for(int i = n; i >= 1; i--)
69             {
70                 while(p && M[st[p]][j] < M[i][j]) p--;
71                 d[i][j] = p ? (st[p] - i - 1) : (n - i);
72                 st[++p] = i;
73             }
74         }
75 
76 
77         ui ans = 0;
78         for(int i = 1; i <= n; i++)
79         {
80             for(int j = 1; j <= m; j++)
81             {
82                 int L = l[i][j], R = r[i][j];
83                 int U = u[i][j], D = d[i][j];
84                 ans = ans + M[i][j] * f[L][R] * f[U][D];
85             }
86         }
87         printf("%u\n", ans);
88 
89     }
90     return 0;
91 }
Aguin

 

HDU 5450 Dertouzos

在打筛表的时候就可以算出md了。然后就是题解那样搞。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1e7 + 10;
 6 int pr[maxn], md[maxn];
 7 
 8 void GetPrime()
 9 {
10     for(int i = 2; i < maxn; i++)
11     {
12         if(!pr[i]) pr[++pr[0]] = i, md[i] = i;
13         for(int j = 1; j <= pr[0] && pr[j] * i < maxn; j++)
14         {
15             pr[i*pr[j]] = 1;
16             md[i*pr[j]] = pr[j];
17             if(i % pr[j] == 0) break;
18         }
19     }
20 }
21 
22 int main(void)
23 {
24     GetPrime();
25     int T;
26     scanf("%d", &T);
27     while(T--)
28     {
29         int n, d;
30         scanf("%d %d", &n, &d);
31         int ans = 0;
32         if(d < maxn) ans = upper_bound(pr + 1, pr + pr[0], min((n - 1) / d, md[d])) - pr - 1;
33         else for(int i = 1; i <= pr[0] && pr[i] <= (n - 1) / d; i++)
34         {
35             ans++;
36             if(d % pr[i] == 0) break;
37         }
38         printf("%d\n", ans);
39     }
40     return 0;
41 }
Aguin

 

HDU 5451 Eades

对于每个数找区间那里不会搞,找了个AC代码抄了一下。

大概是用一个随便什么存一下区间最大值,先solve(l, r)算这个区间的最大值的贡献,

然后找到所有最大值的位置,所有的最大值把l,r切成了好多小区间,每个小区间递归一下。

这样搞也许可能大概是差不多nlogn的吧。

然后就是纯粹的FFT,虽然不懂怎么搞但是抄个板还是可以的。

然而算了半天发现推的式子和AC代码不一样QAQ。

结果竟然也对了真是神奇哦。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <cmath>
  6 #include <algorithm>
  7 using namespace std;
  8 const int maxn = 1e5 + 10;
  9 typedef long long LL;
 10 vector<int> p[maxn];
 11 int n, a[maxn], b[maxn], z[maxn];
 12 
 13 // ST
 14 int rmq[maxn][20];
 15 void RMQ_init()
 16 {
 17     for(int i = 1; i <= n; i++) rmq[i][0] = a[i];
 18     for(int j = 1; (1 << j) <= n; j++)
 19         for(int i = 1; i + ( 1 << j ) - 1 <= n; i++)
 20             rmq[i][j] = max(rmq[i][j-1] , rmq[i+(1<<j-1)][j-1]);
 21 }
 22 
 23 int RMQ_query(int l, int r)
 24 {
 25     int k = 0;
 26     while( ( 1 << (k + 1) ) <= r - l + 1 ) k++;
 27     return max(rmq[l][k], rmq[r-(1<<k)+1][k]);
 28 }
 29 
 30 
 31 // FFT
 32 const double Pi = acos(-1.0);
 33 
 34 struct complex
 35 {
 36     double r, i;
 37     complex(double r = 0, double i = 0): r(r), i(i) {}
 38     complex operator + (const complex &ot) const
 39     {
 40         return complex(r + ot.r, i + ot.i);
 41     }
 42     complex operator - (const complex &ot) const
 43     {
 44         return complex(r - ot.r, i - ot.i);
 45     }
 46     complex operator * (const complex &ot) const
 47     {
 48         return complex(r * ot.r - i * ot.i, r * ot.i + i * ot.r);
 49     }
 50 } x1[maxn<<2], x2[maxn<<2];
 51 
 52 void change(complex * y, int len)
 53 {
 54     for(int i = 1, j = len >> 1; i < len - 1; i++)
 55     {
 56         if(i < j) swap(y[i], y[j]);
 57         int k = len >> 1;
 58         while(j >= k) j -= k, k >>= 1;
 59         j += k;
 60     }
 61 }
 62 
 63 void FFT(complex * y, int len, int on)
 64 {
 65     change(y, len);
 66     for(int h = 2; h <= len; h <<= 1)
 67     {
 68         complex wn = complex(cos(on * 2 * Pi / h), sin(on * 2 * Pi / h));
 69         for(int j = 0; j < len; j += h)
 70         {
 71             complex w = complex(1, 0);
 72             for(int k = j; k < j + h / 2; k++)
 73             {
 74                 complex u = y[k];
 75                 complex t = y[k+h/2] * w;
 76                 y[k] = u + t;
 77                 y[k+h/2] = u - t;
 78                 w = w * wn;
 79             }
 80         }
 81     }
 82     if(on == -1)
 83     {
 84         for(int i = 0; i < len; i++)
 85         {
 86             y[i].r /= len;
 87         }
 88     }
 89 }
 90 
 91 void cal(int * a, int * b, int l)
 92 {
 93     int len = 1;
 94     while(len < l * 2) len <<= 1;
 95     for(int i = 0; i < l; i++)
 96     {
 97         x1[i] = complex(a[i], 0);
 98         x2[i] = complex(b[i], 0);
 99     }
100     for(int i = l; i < len; i++) x1[i] = x2[i] = complex(0, 0);
101     FFT(x1, len, 1);
102     FFT(x2, len, 1);
103     for(int i = 0; i < len; i++) x1[i] = x1[i] * x2[i];
104     FFT(x1, len, -1);
105     for(int i = 1; i < l; i++)
106         z[i] += x1[l-1-i].r + 0.5;
107 }
108 
109 void solve(int l, int r)
110 {
111     if(l > r) return;
112     if(l == r) {z[1]++; return;}
113     int M = RMQ_query(l, r);
114     int x = lower_bound(p[M].begin(), p[M].end(), l) - p[M].begin();
115     int y = upper_bound(p[M].begin(), p[M].end(), r) - p[M].begin() - 1;
116 
117     a[0] = p[M][x] - l + 1;
118     for(int i = x + 1; i <= y; i++) a[i-x] = p[M][i] - p[M][i-1];
119     a[y-x+1] = r - p[M][y] + 1;
120 
121     for(int i = 0; i <= y - x + 1; i++) b[i] = a[y-x+1-i];
122 
123     cal(a, b, y - x + 2);
124 
125     solve(l, p[M][x] - 1);
126     for(int i = x + 1; i <= y; i++) solve(p[M][i-1] + 1, p[M][i] - 1);
127     solve(p[M][y] + 1, r);
128 }
129 
130 int main(void)
131 {
132     int T;
133     scanf("%d", &T);
134     while(T--)
135     {
136         scanf("%d", &n);
137         for(int i = 1; i <= n; i++) p[i].clear();
138         for(int i = 1; i <= n; i++)
139         {
140             scanf("%d", a + i);
141             p[a[i]].push_back(i);
142         }
143         RMQ_init();
144         memset(z, 0, sizeof(z));
145         solve(1, n);
146         LL ans = 0;
147         for(int i = 1; i <= n; i++) ans += (LL) i ^ z[i];
148         printf("%I64d\n", ans);
149     }
150     return 0;
151 }
Aguin

 

补题

HDU 5584 LCM Walk

gcd不会变呀。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int gcd(int a, int b)
 7 {
 8     return a % b ? gcd(b, a % b) : b;
 9 }
10 
11 int main(void)
12 {
13     int T;
14     scanf("%d", &T);
15     for(int kase = 1; kase <= T; kase++)
16     {
17         int a, b;
18         scanf("%d %d", &a, &b);
19         int ans = 1;
20         while(1)
21         {
22             if(a < b) swap(a, b);
23             int tmp = 1 + b / gcd(a, b);
24             if(a % tmp) break;
25             a /= tmp;
26             if(gcd(a, b) != b / (tmp - 1)) break;
27             ans++;
28         }
29         printf("Case #%d: %d\n", kase, ans);
30     }
31     return 0;
32 }
Aguin

 

7.25

HDU 5487 Difference of Languages

BFS。如果想到状态用<state 1, state 2>表示就好写了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 typedef pair<int, int> pii;
 7 
 8 int is[2][1111], nxt[2][1111][26];
 9 
10 pii pre[1111][1111];
11 int vis[1111][1111];
12 int a[1111][1111];
13 
14 queue<pii> Q;
15 
16 void ans_print(pii cur)
17 {
18     int c1 = cur.first, c2 = cur.second;
19     if(c1 || c2)
20     {
21         ans_print(pre[c1][c2]);
22         printf("%c", a[c1][c2] + 'a');
23     }
24 }
25 
26 int main(void)
27 {
28     int T;
29     scanf("%d", &T);
30     for(int kase = 1; kase <= T; kase++)
31     {
32         memset(is, 0, sizeof(is));
33         memset(vis, 0, sizeof(vis));
34         memset(nxt, -1, sizeof(nxt));
35 
36         int N1, M1, K1;
37         scanf("%d %d %d", &N1, &M1, &K1);
38         for(int i = 0; i < K1; i++)
39         {
40             int x;
41             scanf("%d", &x);
42             is[0][x] = 1;
43         }
44         for(int i = 0; i < M1; i++)
45         {
46             int p, q;
47             char s[10];
48             scanf("%d %d %s", &p, &q, s);
49             nxt[0][p][s[0]-'a'] = q;
50         }
51 
52         int N2, M2, K2;
53         scanf("%d %d %d", &N2, &M2, &K2);
54         for(int i = 0; i < K2; i++)
55         {
56             int x;
57             scanf("%d", &x);
58             is[1][x] = 1;
59         }
60         for(int i = 0; i < M2; i++)
61         {
62             int p, q;
63             char s[10];
64             scanf("%d %d %s", &p, &q, s);
65             nxt[1][p][s[0]-'a'] = q;
66         }
67 
68         while(!Q.empty()) Q.pop();
69 
70         int ok = 0;
71         pii ans;
72         Q.push(pii(0, 0));
73         while(!Q.empty())
74         {
75             pii tmp = Q.front(); Q.pop();
76             int c1 = tmp.first, c2 = tmp.second;
77             if(is[0][c1] && !is[1][c2] || !is[0][c1] && is[1][c2]){ans = tmp, ok = 1; break;}
78 
79             for(int i = 0; i < 26; i++)
80             {
81                 int nx1 = N1, nx2 = N2;
82                 if(c1 < N1 && nxt[0][c1][i] != -1) nx1 = nxt[0][c1][i];
83                 if(c2 < N2 && nxt[1][c2][i] != -1) nx2 = nxt[1][c2][i];
84                 if(vis[nx1][nx2]) continue;
85                 vis[nx1][nx2] = 1;
86                 pre[nx1][nx2] = pii(c1, c2);
87                 a[nx1][nx2] = i;
88                 Q.push(pii(nx1, nx2));
89             }
90         }
91 
92         printf("Case #%d: ", kase);
93         if(ok) ans_print(ans), puts("");
94         else puts("0");
95 
96     }
97     return 0;
98 }
Aguin

 

posted @ 2016-07-24 10:16  Aguin  阅读(163)  评论(0编辑  收藏  举报