zoukankan      html  css  js  c++  java
  • ZOJ Monthly, March 2018 Solution

    A - Easy Number Game

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 100010
     6 ll arr[N];
     7 int n, m;
     8 
     9 int main()
    10 {
    11     int t; scanf("%d", &t);
    12     while (t--)
    13     {
    14         scanf("%d%d", &n, &m);
    15         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i);
    16         sort(arr + 1, arr + 1 + n);
    17         ll res = 0;
    18         for (int i = 1; i <= m; ++i)
    19             res += arr[i] * arr[2 * m - i + 1]; 
    20         printf("%lld
    ", res);
    21     }
    22     return 0;
    23 }
    View Code

    B - Lucky Man

    题意:判断大数开根后的奇偶性

    思路:牛顿迭代法

     1 import java.io.BufferedInputStream;
     2 import java.util.Scanner;
     3 import java.math.*;
     4 
     5 public class Main {
     6 
     7     public static void main(String[] args) {
     8         Scanner in = new Scanner(new BufferedInputStream(System.in));
     9         int t = in.nextInt();
    10         BigInteger a, x, two; String n;
    11         two = BigInteger.valueOf(2);
    12         while (t-- != 0)
    13         {
    14             n = in.next();
    15             a = new BigInteger(n);
    16             x = new BigInteger(n.substring(0, n.length() / 2 + 1));
    17             while (a.compareTo(x.multiply(x)) < 0)
    18                 x = x.add(a.divide(x)).divide(two);
    19             if (x.mod(two).compareTo(BigInteger.ZERO) == 0) System.out.println(0);
    20             else System.out.println(1);
    21         }
    22         in.close();
    23     }
    24 }
    View Code

    C - Travel along the Line

    题意:一维坐标系中,刚开始位于原点,有$frac{1}{4}$的概率 坐标 +1 和 -1  有$frac {1}{2} 的概率 不动$  求在第n秒的时候恰好到达第m个位置的概率

    思路:考虑把一个0拆成两个0,变成四种操作,这样四种操作是等概率的,那么所有的可能性就是 $4^n$ 再考虑符合条件的方案数

    可以考虑将m通过坐标变换转化成正的,那么一个满足题意的操作序列肯定是 1 的个数 减去 -1的 个数 恰好为m

    那么我们只需要枚举1的个数,排列组合一下即可

    16说 假如用a 表示 1 的个数  b 表示 -1 的个数 c 表示 0的个数

    那么有$frac {n!} {a! cdot b! cdot c!}$ 但是这里要考虑 多乘上$2^c$ 因为每个0都有两种选择 ,可以是$0_1 或者 是 0_2$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 100010
     6 ll MOD = (ll)1e9 +7;
     7 
     8 ll fac[N], Bit[N];
     9 ll qmod(ll base, ll n)
    10 {
    11     ll res = 1;
    12     while (n)
    13     {
    14         if (n & 1) res = res * base % MOD;
    15         base = base * base % MOD;
    16         n >>= 1;
    17     }
    18     return res;
    19 }
    20 
    21 void Init()
    22 {
    23     fac[0] = 1;
    24     Bit[0] = 1;
    25     for (int i = 1; i < N; ++i) fac[i] = fac[i - 1] * i % MOD;
    26     for (int i = 1; i < N; ++i) Bit[i] = Bit[i - 1] * 2 % MOD;
    27 }
    28 
    29 int n, m;
    30 
    31 int main()
    32 {
    33     Init();
    34     int t; scanf("%d", &t);
    35     while (t--)
    36     {
    37         scanf("%d%d", &n, &m);
    38         if (m < 0) m = -m;
    39         ll p = 0, q = qmod(4, n); 
    40         for (int i = 0; 2 * i + m <= n; ++i)
    41             p = (p + (fac[n] * qmod(fac[i], MOD - 2) %MOD * qmod(fac[i + m], MOD - 2) % MOD * qmod(fac[n - 2 * i - m], MOD - 2) % MOD * Bit[n - 2 * i - m] % MOD)) % MOD;    
    42         ll res = p * qmod(q, MOD - 2) % MOD;
    43         printf("%lld
    ", res);
    44     }
    45     return 0;
    46 }
    View Code

    D - Machine Learning on a Tree

    留坑。

    E - Yet Another Tree Query Problem

    题意:每次询问$[l, r]$ 区间内所有点所在的连通块个数

    思路:先预处理l 为 1    r 为 1 ->n  的答案  考虑删去一个点对后面答案的影响

    将一个点的所有孩子和父亲中,按编号排序

    比如说  点1  连出去的边有  4, 10, 20

    那么 对于右界为 2-3 的  连通块个数少一

    右界为5 - 9 的 连通块个数不变

    右界为 11 - 19 的 连通块个数加1

    BIT区间更新即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 200010
     5 #define pii pair <int, int>
     6 int t, n, q;
     7 vector <int> G[N];
     8 vector <pii> que[N];
     9 int base[N], ans[N];
    10 
    11 struct BIT
    12 {
    13     int a[N];
    14     void init() { memset(a, 0, sizeof a); }
    15     void update(int x, int val)    { for (; x <= n; x += x & -x) a[x] += val; }
    16     void update(int l, int r, int val)
    17     {
    18         if (r < l) return;
    19         update(l, val);
    20         update(r + 1, -val);
    21     }
    22     int query(int x)
    23     {
    24         int res = 0;
    25         for (; x; x -= x & -x)
    26             res += a[x];
    27         return res;
    28     }
    29 
    30 }bit;
    31 
    32 void Run() 
    33 {
    34     scanf("%d", &t);
    35     while (t--)
    36     {
    37         for (int i = 1; i <= n; ++i) G[i].clear(), que[i].clear();
    38         bit.init(); 
    39         scanf("%d%d", &n, &q);
    40         for (int i = 1, u, v; i < n; ++i)
    41         {
    42             scanf("%d%d", &u, &v);
    43             G[u].push_back(v);
    44             G[v].push_back(u);
    45         }
    46         for (int i = 1, l, r; i <= q; ++i)
    47         {
    48             scanf("%d%d", &l, &r);
    49             que[l].emplace_back(r, i);
    50         }
    51         for (int i = 1; i <= n; ++i)
    52         {
    53             int tmp = 1; 
    54             sort(G[i].begin(), G[i].end());
    55             for (auto v : G[i]) if (v < i)   
    56                 --tmp;  
    57             base[i] = base[i - 1] + tmp; 
    58         }
    59         for (int i = 1; i <= n; ++i)
    60         {
    61             for (auto it : que[i])  
    62                 ans[it.second] = base[it.first] + bit.query(it.first); 
    63             G[i].push_back(n + 1);  
    64             int pre = i + 1;   
    65             for (int j = 0, len = G[i].size(), add = -1; j < len; ++j) 
    66             {
    67                 int v = G[i][j];
    68                 if (v < i) continue;
    69                 bit.update(pre, v - 1, add); 
    70                 pre = v; ++add;
    71             }
    72         }
    73         for (int i = 1; i <= q; ++i) printf("%d
    ", ans[i]);
    74     }
    75 }
    76 
    77 int main()
    78 {
    79     #ifdef LOCAL
    80         freopen("Test.in", "r", stdin); 
    81     #endif 
    82 
    83     Run();
    84     return 0;
    85 
    86 }
    View Code

    F - And Another Data Structure Problem

    题意:两种操作,一种是区间立方,一种是区间求和

    思路:考虑这个模数很特殊

    $3^{48} equiv 1 pmod {99970}$

    所以有

    $a^{3^{48}} equiv a pmod {99971}$

    所有任意数做48次后 必然会回到原数 考虑开48棵线段树解决

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 #define ll long long
     6 const ll MOD = 99971;
     7 int t, n, q;
     8 ll arr[N];
     9 
    10 struct SEG
    11 {
    12     ll a[N << 2][49], tmp[49]; 
    13     int lazy[N << 2];
    14     void init() { memset(a, 0, sizeof a); }
    15     void pushup(int id)
    16     {
    17         for (int i = 0; i < 48; ++i) 
    18             a[id][i] = (a[id << 1][(i + lazy[id << 1]) % 48] + a[id << 1 | 1][(i + lazy[id << 1 | 1]) % 48]) % MOD; 
    19     }
    20     void pushdown(int id)
    21     {
    22         if (!lazy[id]) return; 
    23         lazy[id << 1] = (lazy[id << 1] + lazy[id]) % 48;
    24         lazy[id << 1 | 1] = (lazy[id << 1 | 1] + lazy[id]) % 48;
    25         for (int i = 0; i < 48; ++i) tmp[i] = a[id][(i + lazy[id]) % 48];
    26         memcpy(a[id], tmp, sizeof tmp);
    27         lazy[id] = 0;
    28     }
    29     void build(int id, int l, int r)
    30     {
    31         lazy[id] = 0;
    32         if (l == r)
    33         {
    34             a[id][0] = arr[l];
    35             for (int i = 1; i < 48; ++i)
    36                 a[id][i] = a[id][i - 1] * a[id][i - 1] % MOD * a[id][i - 1] % MOD;
    37             return;  
    38         }
    39         int mid = (l + r) >> 1;
    40         build(id << 1, l, mid);
    41         build(id << 1 | 1, mid + 1, r);
    42         pushup(id); 
    43     }
    44     void update(int id, int l, int r, int ql, int qr, int val)
    45     {
    46         if (l >= ql && r <= qr)
    47         {
    48             lazy[id] = (lazy[id] + val) % 48; 
    49             return;
    50         }
    51         pushdown(id);
    52         int mid = (l + r) >> 1;
    53         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
    54         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val);
    55         pushup(id);
    56     }
    57     ll query(int id, int l, int r, int ql, int qr)
    58     {
    59         if (l >= ql && r <= qr) return a[id][lazy[id]];
    60         pushdown(id);
    61         int mid = (l + r) >> 1;
    62         ll res = 0;
    63         if (ql <= mid) res = (res + query(id << 1, l, mid, ql, qr)) % MOD;
    64         if (qr > mid) res = (res + query(id << 1 | 1, mid + 1, r, ql, qr)) % MOD;
    65         //pushup(id);
    66         return res;
    67     }
    68 }seg;
    69 
    70 void Run() 
    71 {
    72     scanf("%d", &t);
    73     while (t--)
    74     {
    75         scanf("%d%d", &n, &q);
    76         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i), arr[i] %= MOD;
    77         seg.build(1, 1, n); 
    78         for (int i = 1, op, l, r; i <= q; ++i)
    79         {
    80             scanf("%d%d%d", &op, &l, &r);
    81             if (op == 1) seg.update(1, 1, n, l, r, 1);
    82             else printf("%lld
    ", seg.query(1, 1, n, l, r));
    83         }
    84     }
    85 }
    86 
    87 int main()
    88 {
    89     #ifdef LOCAL
    90         freopen("Test.in", "r", stdin); 
    91     #endif 
    92 
    93     Run();
    94     return 0;
    95 
    96 }
    View Code
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 #define ll long long
     6 const ll MOD = 99971;
     7 int t, n, q;
     8 ll arr[N];
     9 
    10 struct SEG
    11 {
    12     ll a[N << 2][50], tmp[50]; 
    13     int lazy[N << 2];
    14     void pushup(int id)
    15     {
    16         for (int i = 0; i < 48; ++i) 
    17             a[id][i] = (a[id << 1][(i + lazy[id << 1]) % 48] + a[id << 1 | 1][(i + lazy[id << 1 | 1]) % 48]) % MOD; 
    18     }
    19     void build(int id, int l, int r)
    20     {
    21         lazy[id] = 0;
    22         if (l == r)
    23         {
    24             a[id][0] = arr[l];
    25             for (int i = 1; i < 48; ++i)
    26                 a[id][i] = a[id][i - 1] * a[id][i - 1] % MOD * a[id][i - 1] % MOD;
    27             return;  
    28         }
    29         int mid = (l + r) >> 1;
    30         build(id << 1, l, mid);
    31         build(id << 1 | 1, mid + 1, r);
    32         pushup(id); 
    33     }
    34     void update(int id, int l, int r, int ql, int qr, int val)
    35     {
    36         if (l >= ql && r <= qr)
    37         {
    38             lazy[id] = (lazy[id] + 1) % 48; 
    39             return;
    40         }
    41         int mid = (l + r) >> 1;
    42         if (ql <= mid) update(id << 1, l, mid, ql, qr, val);
    43         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, val); 
    44         pushup(id);
    45     }
    46     ll query(int id, int l, int r, int ql, int qr, int k = 0)
    47     {
    48         k = (k + lazy[id]) % 48;
    49         if (l >= ql && r <= qr) return a[id][k];
    50         int mid = (l + r) >> 1;
    51         ll res = 0;
    52         if (ql <= mid) res = (res + query(id << 1, l, mid, ql, qr, k)) % MOD;
    53         if (qr > mid) res = (res + query(id << 1 | 1, mid + 1, r, ql, qr, k)) % MOD;
    54         return res;
    55     }
    56 }seg;
    57 
    58 void Run() 
    59 {
    60     scanf("%d", &t);
    61     while (t--)
    62     {
    63         scanf("%d%d", &n, &q);
    64         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i), arr[i] %= MOD;
    65         seg.build(1, 1, n); 
    66         for (int i = 1, op, l, r; i <= q; ++i)
    67         {
    68             scanf("%d%d%d", &op, &l, &r);
    69             if (op == 1) seg.update(1, 1, n, l, r, 1);
    70             else printf("%lld
    ", seg.query(1, 1, n, l, r));
    71         }
    72     }
    73 }
    74 
    75 int main()
    76 {
    77     #ifdef LOCAL
    78         freopen("Test.in", "r", stdin); 
    79     #endif 
    80 
    81     Run();
    82     return 0;
    83 
    84 }
    View Code

    G - Neighboring Characters

    留坑。

    H - Happy Sequence ZOJ

    题意:用1-n的数,每个数可以用无限次,组成长度为m的序列,求有多少个序列满足 $gcd(b_i, b_{i +1}) = b_{i}$

    思路:考虑枚举序列里面不同的数的个数,根据题目范围,最多有10个不同的数,然后隔板法求方案数

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 long long f[15];
     6 long long C[15];
     7 long long MOD;
     8 int p[15];
     9 int n, m;
    10 
    11 void dp(int t) {
    12     int j;
    13     j = 2;
    14     while (p[t - 1] * j <= n) {
    15         p[t] = p[t - 1] * j;
    16         f[t]++;
    17         dp(t + 1);
    18         j++;
    19     }
    20 }
    21 
    22 ll qmod(ll base, ll n)
    23 {
    24     ll res = 1;
    25     while (n)
    26     {
    27         if (n & 1) res = res * base % MOD;
    28         base = base * base % MOD;
    29         n >>= 1;
    30     }
    31     return res;
    32 }
    33 
    34 int main()
    35 {
    36     int i, j, t;
    37     long long ans;
    38     scanf("%d", &t);
    39     MOD = 1000000007;
    40     while (t--) {
    41         scanf("%d %d", &n, &m);
    42         memset(f, 0, sizeof f);
    43         memset(p, 0, sizeof p);
    44         ans = 0;
    45         C[0] = 1;
    46         for (i = 1; i <= 11 ; ++i)
    47             C[i] = (C[i - 1] * (m - i) % MOD * qmod(i, MOD - 2)) % MOD;
    48         for (i = 1; i <= n; ++i) {
    49             p[1] = i;
    50             ++f[1];
    51             dp(2);
    52         }
    53         for (i = 1; i <= 11; ++i) {
    54             ans = (ans + f[i] * C[i - 1] % MOD) % MOD;
    55         }
    56         printf("%lld
    ",ans);
    57     }
    58     return 0;
    59 }
    View Code

    I - Your Bridge is under Attack

     留坑。

    J - Super Brain

    水。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int n;
     6 int cnt[N * 10], a[N], b[N];
     7 
     8 int main()
     9 {
    10     int t; scanf("%d", &t);
    11     while (t--)
    12     {
    13         scanf("%d", &n);
    14         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    15         for (int i = 1; i <= n; ++i) scanf("%d", b + i);
    16         memset(cnt, 0, sizeof cnt);
    17         for (int i = 1; i <= n; ++i) ++cnt[a[i]];
    18         int res = 0;
    19         for (int i = 1; i <= n; ++i) if (cnt[b[i]] == 1) 
    20         {
    21             res = b[i];
    22             break;
    23         }
    24         printf("%d
    ", res);
    25     }
    26     return 0;
    27 }
    View Code
  • 相关阅读:
    November 13th 2016 Week 47th Sunday The 1st Day
    November 12th 2016 Week 46th Saturday
    November 11th 2016 Week 46th Friday
    November 10th 2016 Week 46th Thursday
    November 9th 2016 Week 46th Wednesday
    November 8th 2016 Week 46th Tuesday
    windows 7文件共享方法
    Win7无线网络共享设置方法
    常量指针和指针常量
    如何查找局域网的外网ip
  • 原文地址:https://www.cnblogs.com/Dup4/p/9845982.html
Copyright © 2011-2022 走看看