• 第三周 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
  • 相关阅读:
    编程范式 epesode7,8 stack存放指针类型and heap,register
    编程范式 episode 6 实现stack 栈功能_ to do
    C 运算符优先级
    编程范式 episode3 and 4,5
    编程范式 epesode2 negative values, float 精度
    C 数据类型 长度
    memcpy code
    排序算法 2 qsort 库函数,泛型函数
    sin, miss the mark, correct our aim and try again
    排序算法 1
  • 原文地址:https://www.cnblogs.com/Aguin/p/5700190.html
Copyright © 2020-2023  润新知