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
  • 相关阅读:
    LINUX查看进程开始时间、结束时间、运行时间
    excel字符处理函数
    oracle RMAN参数配置详解
    Linux添加双IP
    免费软电话 — XLite 的安装及配置向导
    Asterisk实现寻呼对讲广播的Page()命令详解
    自动化工具的重要性
    负载均衡之应用请求路由模块的使用(ARR)(七)[使用ARR来实现主机名共享]
    负载均衡之应用请求路由模块的使用(ARR)(二)[安装]
    需求管理随笔
  • 原文地址:https://www.cnblogs.com/Dup4/p/9845982.html
Copyright © 2011-2022 走看看