ACM-ICPC 2018 徐州赛区网络预赛 Solution

A. Hard to prepare

题意:

思路:

$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i$ (n 是奇数)

$\sum_{i = 0}^{i = n - 1} C_n^i \cdot t^{n - 1} * (-1)^i + t$ (n 是偶数)

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1000010
 6 
 7 const ll MOD = (ll)1e9 + 7;
 8 
 9 int t, n, k; 
10 ll inv[N];
11 ll Bit[N];
12 ll Bitt[N];
13 
14 inline void Init()
15 {
16     inv[1] = 1;
17     for (int i = 2; i < N; ++i) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
18     Bit[0] = 1;
19     for (int i = 1; i < N; ++i) Bit[i] = (Bit[i - 1] * 2) % MOD;
20 }
21 
22 inline void init()
23 {
24     Bitt[0] = 1; ll tmp = Bit[k];
25     for (int i = 1; i <= n; ++i) Bitt[i] = (Bitt[i - 1] * tmp) % MOD; 
26 }
27 
28 inline void Run()
29 {
30     scanf("%d", &t); Init();
31     while (t--)
32     {
33         scanf("%d%d", &n, &k); 
34         if (k == 1)
35         {
36             puts("2"); 
37             continue;
38         }
39         else if (n == 1)
40         {
41             printf("%lld\n",Bit[k]); 
42             continue;
43         }
44         init();
45         ll res = 0;
46         ll C = 1;
47         for (int i = 0; i < n; ++i)
48         {
49             res = (res + (C * Bitt[n - i] % MOD * ((i & 1) ? -1 : 1) + MOD) % MOD) % MOD;
50             C = C * (n - i) % MOD * inv[i + 1] % MOD;
51         }
52         res = (res + (Bit[k] * ((n & 1) ? 0 : 1)) % MOD + MOD) % MOD; 
53         printf("%lld\n", res);
54     }
55 }
56 
57 int main()
58 {
59     #ifdef LOCAL  
60         freopen("Test.in", "r", stdin);
61     #endif  
62 
63     Run();
64     return 0;
65 }
View Code

B. BE, GE or NE

题意:每一轮有三种操作, 加上a 减去b 或者 取负 当且仅当 a, b, c 不为0时,对应的操作有效,给出一个上界和一个下界 大于等于上界就是 Good Ending 小于等于下界 就是 Bad Ending 否则就是 Normal Ending  两个人轮流操作,第一个人想要Good Ending 第二个人想要 Bad Ending  两个人操作最优,求最后的结局

思路:dp[i][j] 表示 第几轮 数字是多少的时候 ,记忆化爆搜 因为数字在$[-100, 100]$

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef long long ll;
  6 
  7 const int MOD = (int)1e9 + 7;
  8 const int INF = 0x3f3f3f3f;
  9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
 10 const int maxn = (int)1e3 + 10;
 11 
 12 struct node {
 13     int a, b, c;
 14     inline node() {}
 15     inline node(int a, int b, int c) :a(a), b(b), c(c) {}
 16 }arr[maxn];
 17 
 18 int n, m, l, k;
 19 int type[maxn][maxn];//1 good  0 normal  -1 bad
 20 int vis[maxn][maxn];
 21 
 22 inline void Init()
 23 {
 24     memset(vis, 0, sizeof vis);
 25     memset(type, 0, sizeof type);
 26 }
 27 
 28 inline int DFS(int idx, int state)
 29 {
 30     if (idx > n)
 31     {
 32         if (state <= l) return -1;
 33         else if (state >= k) return 1;
 34         else return 0;
 35     }
 36     if (vis[idx][state]) return type[idx][state];
 37     vis[idx][state] = 1;
 38     int res = 0;
 39     //a
 40     int A = 2, B = 2, C = 2;
 41     if (arr[idx].a)
 42     {
 43         A = DFS(idx + 1, min(100, state + arr[idx].a));
 44     }
 45     //b
 46     if (arr[idx].b)
 47     {
 48         B = DFS(idx + 1, max(-100, state - arr[idx].b));
 49     }
 50     //c
 51     if (arr[idx].c)
 52     {
 53         C = DFS(idx + 1, max(-100, min(100, state * -arr[idx].c)));
 54     }
 55     if ((A == 1 || A == 2)&& (B == 1 || B == 2) && (C == 1 || C == 2) && (idx & 1) == 0)
 56     {
 57         type[idx][state] = 1;
 58         return 1;
 59     }
 60     else if ((A == -1 || A == 2) && (B == -1 || B == 2) && (C == -1 || C == 2) && (idx & 1) == 1)
 61     {
 62         type[idx][state] = -1;
 63         return -1;
 64     }
 65     else if ((A == 1 || B == 1 || C == 1) && (idx & 1) == 1)
 66     {
 67         type[idx][state] = 1;
 68         return 1;
 69     }
 70     else if ((A == -1 || B == -1 || C == -1) && (idx & 1) == 0)
 71     {
 72         type[idx][state] = -1;
 73         return -1;
 74     }
 75     else
 76     {
 77         type[idx][state] = 0;
 78         return 0;
 79     }
 80 }
 81 
 82 inline void RUN()
 83 {
 84     while (~scanf("%d %d %d %d", &n, &m, &k, &l))
 85     {
 86         Init(); 
 87         for (int i = 1; i <= n; ++i)
 88         {
 89             scanf("%d %d %d", &arr[i].a, &arr[i].b, &arr[i].c);
 90         }
 91         int ans = DFS(1, m);
 92         if (ans == 1)
 93         {
 94             puts("Good Ending");
 95         }
 96         else if (ans == -1)
 97         {
 98             puts("Bad Ending");
 99         }
100         else
101         {
102             puts("Normal Ending");
103         }
104     }
105 }
106 
107 int main()
108 {
109 #ifdef LOCAL_JUDGE
110     freopen("Text.txt", "r", stdin);
111 #endif // LOCAL_JUDGE
112 
113     RUN();
114 
115 #ifdef LOCAL_JUDGE
116     fclose(stdin);
117 #endif // LOCAL_JUDGE
118 }
View Code

C. Cacti Lottery

留坑。

D. Easy Math

留坑。

E. End Fantasy VIX

留坑。

F. Features Track

水。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 #define ll long long
 6 
 7 typedef pair <ll, ll> pii;
 8 
 9 int t, n, tot;
10 ll ans, x, y;
11 map <pii, pii> mp; 
12 
13 inline void Run()
14 {
15     scanf("%d", &t);
16     while (t--)
17     {
18         scanf("%d", &n); mp.clear(); ans = 0;
19         for (int i = 1; i <= n; ++i)
20         {
21             scanf("%d", &tot);
22             for (int j = 1; j <= tot; ++j)
23             {
24                 scanf("%lld%lld", &x, &y);
25                 if (mp[pii(x, y)].second == i - 1) ++mp[pii(x, y)].first;
26                 else if (mp[pii(x, y)].second == i) continue;
27                 else mp[pii(x, y)].first = 1;
28                 ans = max(ans, mp[pii(x, y)].first);
29                 mp[pii(x, y)].second = i;
30             }
31         }
32         printf("%lld\n", ans);
33     }
34 }
35 
36 int main()
37 {
38     #ifdef LOCAL  
39         freopen("Test.in", "r", stdin);
40     #endif  
41 
42     Run();
43     return 0;
44 }
View Code

G. Trace

题意:每次给出一个点,然后就会形成两条线,如果后面的矩形覆盖了前面的边,那么这条边就消失了, 最后求剩下的边是多少

思路:分别处理x轴,y轴,然后排序,然后扫过去,每次加上自己的边长以及减去标号比自己小的并且长度比自己高的个数乘自己的边长

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define N 50010
  5 #define ll long long
  6 
  7 int n;
  8 
  9 struct node
 10 {
 11     int l, r;
 12     int lazy, sum;
 13     inline node() {}
 14     inline node(int _l, int _r)
 15     {
 16         l = _l, r = _r;
 17         lazy = -1;
 18         sum = 0;
 19     }
 20 }tree[N << 2];
 21 
 22 inline void pushup(int id)
 23 {
 24     tree[id].sum = tree[id << 1].sum + tree[id << 1 | 1].sum;
 25 }
 26 
 27 inline void pushdown(int id)
 28 {
 29     if (tree[id].l >= tree[id].r) return;
 30     if (~tree[id].lazy) 
 31     {
 32         int lazy = tree[id].lazy; tree[id].lazy = -1;
 33         tree[id << 1].lazy = tree[id << 1 | 1].lazy = lazy;
 34         tree[id << 1].sum = tree[id << 1 | 1].sum = 0;
 35     }
 36 }
 37 
 38 inline void build(int id, int l, int r) 
 39 {
 40     tree[id] = node(l, r);
 41     if (l == r) return;
 42     int mid = (l + r) >> 1;
 43     build(id << 1, l, mid);
 44     build(id << 1 | 1, mid + 1, r);
 45 }
 46 
 47 inline void update(int id, int l, int r, int val)
 48 {
 49     if (tree[id].l >= l && tree[id].r <= r)
 50     {
 51         tree[id].sum = val; 
 52         tree[id].lazy = val;
 53         return;
 54     }
 55     pushdown(id);
 56     int mid = (tree[id].l + tree[id].r) >> 1;
 57     if (l <= mid) update(id << 1, l, r, val); 
 58     if (r > mid) update(id << 1 | 1, l, r, val);
 59     pushup(id);
 60 }
 61 
 62 inline int query(int id, int l, int r)
 63 {
 64     if (tree[id].l >= l && tree[id].r <= r) return tree[id].sum;
 65     pushdown(id);
 66     int mid = (tree[id].l + tree[id].r) >> 1;
 67     int res = 0;
 68     if (l <= mid) res += query(id << 1, l, r);
 69     if (r > mid) res += query(id << 1 | 1, l, r);
 70     return res;
 71 }
 72 
 73 struct DT
 74 {
 75     int pos;
 76     ll x, y;
 77     inline void scan(int _pos)
 78     {
 79         pos = _pos;
 80         scanf("%lld%lld", &x, &y);
 81     }
 82 }arr[N];
 83 
 84 inline bool cmp1(DT a, DT b)
 85 {
 86     return a.x < b.x;
 87 }
 88 
 89 inline bool cmp2(DT a, DT b)
 90 {
 91     return a.y < b.y;
 92 }
 93 
 94 inline void Run()
 95 {
 96     while (scanf("%d", &n) != EOF)
 97     {
 98         for (int i = 1; i <= n; ++i) arr[i].scan(i);
 99         build(1, 1, n); 
100         sort(arr + 1, arr + 1 + n, cmp1);
101         ll res = 0;
102         for (int i = 1; i <= n; ++i)
103         {
104             res += arr[i].y;
105             int pos = query(1, 1, arr[i].pos);
106             res -= arr[i].y * pos; 
107             update(1, 1, arr[i].pos, 0);
108             update(1, arr[i].pos, arr[i].pos, 1);
109         }
110         sort(arr + 1, arr + 1 + n, cmp2);
111         update(1, 1, n, 0); 
112         for (int i = 1; i <= n; ++i)
113         {
114             res += arr[i].x;
115             int pos = query(1, 1, arr[i].pos);
116             res -= arr[i].x * pos;
117             update(1, 1, arr[i].pos, 0);
118             update(1, arr[i].pos, arr[i].pos, 1);
119         }
120         printf("%lld\n", res);
121     }
122 }
123 
124 int main()
125 {
126     #ifdef LOCAL  
127         freopen("Test.in", "r", stdin);
128     #endif  
129 
130     Run();
131     return 0;
132 }
View Code

H. Ryuji doesn't want to study

题意:两个操作,第一种是查询$[L, R]$ 区间内 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

第二种是改变一个数

思路:线段树,记录两个值,一个是sum,另一个是 $a[L] * len + a[L + 1] * (len - 1) + ... + a[R] * 1$

考虑合并的时候 显然两个区间合并,相当于左区间的长度增加了右区间的长度,那么只需要多加上左区间的sum * 右区间长度

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

I. Characters with Hash

水。

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const int MOD = (int)1e9 + 7;
 8 const int INF = 0x3f3f3f3f;
 9 const ll INFLL = 0x3f3f3f3f3f3f3f3f;
10 const int maxn = (int)1e6 + 10;
11 
12 int n;
13 char s[10];
14 char str[maxn];
15 
16 int arr[maxn];
17 
18 inline void RUN()
19 {
20     int t;
21     scanf("%d", &t);
22     while (t--)
23     {
24         scanf("%d", &n);
25         scanf("%s", s);
26         scanf("%s", str);
27         int len = strlen(str);
28         for (int i = 0; i < len; ++i)
29         {
30             arr[i] = abs(str[i] - s[0]);
31         }
32         int ans = 2 * len;
33         for (int i = 0; i < len; ++i)
34         {
35             if (arr[i] == 0)
36             {
37                 ans -= 2;
38             }
39             else if (arr[i] < 10)
40             {
41                 ans -= 1;
42                 break;
43             }
44             else
45             {
46                 break;
47             }
48         }
49         if (ans == 0) ans = 1;
50         printf("%d\n", ans);
51     }
52 }
53 
54 int main()
55 {
56 #ifdef LOCAL_JUDGE
57     freopen("Text.txt", "r", stdin);
58 #endif // LOCAL_JUDGE
59 
60     RUN();
61 
62 #ifdef LOCAL_JUDGE
63     fclose(stdin);
64 #endif // LOCAL_JUDGE
65 }
View Code

J. Maze Designer
留坑。

K. Morgana Net

留坑。

猜你喜欢

转载自www.cnblogs.com/Dup4/p/9614543.html
今日推荐