CCPC-Wannafly Winter Camp Day3 (Div2, onsite)

Replay


Dup4:

  •  没想清楚就动手写? 写了两百行发现没用?想的还是不够仔细啊。
  • 要有莽一莽的精神

X:

  • 感觉今天没啥输出啊, 就推了个公式?抄了个板子, 然后就一直自闭A。
  • 语文差,题目没理解,导致写了接近三小时的A吧, 最后看了一眼群, 发现自己理解错了。
  • 以及感觉自己最近不会交流,有点毒瘤了。 

A:二十四点*

Solved.

思路:

Div2 暴力跑?

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n;
 6 double arr[20];
 7 
 8 int main()
 9 {
10     while(~scanf("%d", &n))
11     {
12         for(int i = 1; i <= n; ++i) scanf("%lf", arr + i);
13         else if(n == 6) puts("32");
14         else if(n == 10) puts("891");    
15     
16     }
17     return 0;
18 }
View Code
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 const ll MOD = 998244353;
 6 const double eps = 1e-8;
 7 
 8 int n, ans;
 9 double arr[12];
10 double brr[12];
11 
12 int DFS(int len)
13 {
14     if (len == 1)
15     {
16         if (fabs(brr[1] - 24.0) < eps) return 1;
17         else return 0;
18     }
19 
20     for (int i = 1; i <= len; ++i)
21     {
22         for (int j = i + 1; j <= len; ++j)
23         {
24             double a = brr[i], b = brr[j], c = brr[len];
25             brr[j] = c;
26             double tmp = a + b;
27             brr[i] = tmp;
28             if (fabs(tmp - 24.0) < eps) return 1;
29             if (DFS(len - 1)) return 1;
30 
31             tmp = a - b;
32             brr[i] = tmp;
33             if (fabs(tmp - 24.0) < eps) return 1;
34             if (DFS(len - 1)) return 1;
35 
36             tmp = b - a;
37             brr[i] = tmp;
38             if (fabs(tmp - 24.0) < eps) return 1;
39             if (DFS(len - 1)) return 1;
40 
41             tmp = a * b;
42             brr[i] = tmp;
43             if (fabs(tmp - 24.0) < eps) return 1;
44             if (DFS(len - 1)) return 1;
45 
46             tmp = a / b;
47             brr[i] = tmp;
48             if (fabs(tmp - 24.0) < eps) return 1;
49             if (DFS(len - 1)) return 1;
50 
51             tmp = b / a;
52             brr[i] = tmp;
53             if (fabs(tmp - 24.0) < eps) return 1;
54             if (DFS(len - 1)) return 1;
55 
56 
57             brr[i] = a, brr[j] = b, brr[len] = c;
58         }
59     }
60 
61     return 0;
62 }
63 
64 void RUN()
65 {
66     while (~scanf("%d", &n))
67     {
68         for (int i = 1; i <= n; ++i) scanf("%lf", arr + i);
69         ans = 0;
70         for (int i = 0; i < (1 << n); ++i)
71         {
72             int tot = 0;
73             for (int j = 0; j < n; ++j)
74             {
75                 if (i & (1 << j))
76                 {
77                     brr[++tot] = arr[j + 1];
78                 }
79             }
80             int tmp = DFS(tot);
81             ans += tmp;
82         }
83         printf("%d\n", ans);
84     }
85 }
86 
87 int main()
88 {
89     RUN();
90     return 0;
91 }
View Code

F:小清新数论*

Solved.

思路:

$ans = \sum\limits_{d = 1}^n \cdot \mu(d) \sum\limits_{i = 1}^{\frac{n}{d}} \sum\limits_{j = 1}^{\frac{n}{d}} [gcd(i, j) == 1]$

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef long long ll;
 6 
 7 const ll MOD = 998244353;
 8 const int maxn = 1e7 + 10;
 9 
10 bool check[maxn];
11 int prime[maxn];
12 int mu[maxn];
13 ll sum[maxn];
14 
15 void Moblus()
16 {
17     mu[1] = 1;
18     int tot = 0;
19     for(int i = 2; i < maxn; ++i)
20     {
21         if(!check[i])
22         {
23             prime[tot++] = i;
24             mu[i] = -1;
25         }
26         for(int j = 0; j < tot; ++j)
27         {
28             if(i * prime[j] > maxn) break;
29             check[i * prime[j]] = true;
30                if(i % prime[j] == 0)
31             {
32                 mu[i * prime[j]] = 0;
33                 break;
34             }    
35             else
36             {
37                 mu[i * prime[j]] = -mu[i];
38             }
39         }
40     }
41     for(int i = 1; i < maxn; ++i)
42     {
43         sum[i] = (sum[i - 1] + mu[i]) % MOD;
44     }
45 }
46 
47 ll solve(int n, int m)
48 {
49     ll ans = 0;
50     if(n > m) swap(n, m);
51     for(int i = 1, la = 0; i <= n; i = la + 1)
52     {
53         la = min(n / (n / i), m / (m / i));
54         ans += (sum[la] - sum[i - 1]) * (n / i) * (n / i);
55     }
56     return ans;
57 }
58 
59 int n;
60 
61 int main()
62 {
63     Moblus();
64     while(~scanf("%d", &n))
65     {
66         ll ans = 0;
67         for(int i = 1; i <= n; ++i)
68         {
69             ans = (ans + mu[i] * solve(n / i, n / i) % MOD + MOD) % MOD;
70         }
71         printf("%lld\n", ans);
72     }
73     return 0;
74 }
View Code

G:排列

Solved.

签到。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define N 100010
 5 int n, q[N], p[N], vis[N];
 6 
 7 int main()
 8 {
 9     while (scanf("%d", &n) != EOF)
10     {
11         memset(vis, 0, sizeof vis);
12         memset(p, 0, sizeof p);
13         for (int i = 1; i <= n; ++i) scanf("%d", q + i);
14         int j = 1;
15         for (int i = 1; i <= n; ++i)
16         {
17             if (i == 1 || q[i] < q[i - 1])
18             {
19                 vis[j] = 1;
20                 p[q[i]] = j;
21                 ++j;
22             }
23         }
24         for (int i = 1; i <= n; ++i) if (!p[i]) 
25             p[i] = j++;
26         for (int i = 1; i <= n; ++i) printf("%d%c", p[i], " \n"[i == n]);
27     }
28     return 0;
29 }
View Code

H:涂鸦*

Solved.

思路:

对于某一个点来说,它被染成黑点的概率是$\frac{(x - l + 1) \cdot (r - x + 1) \cdot 2}{(r - l + 1) \cdot (r - l + 2)}$ 

然后二维BIT维护矩形,最后将所有未被矩形覆盖的期望加起来即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define ll long long
 5 #define N 1010
 6 const ll p = (ll)998244353;
 7 const ll MOD = (ll)998244353;
 8 int n, m, q;
 9 ll inv[N];
10 int ans[N][N];
11 
12 namespace BIT
13 {
14     int a[N][N];
15     void init() { memset(a, 0, sizeof a); }
16     void update(int x, int y, int v)
17     {
18         for (int i = x; i > 0; i -= i & -i)
19             for (int j = y; j > 0; j -= j & -j)
20                 a[i][j] += v;
21     }
22     int query(int x, int y)
23     {
24         int res = 0;
25         for (int i = x; i < N; i += i & -i)
26             for (int j = y; j < N; j += j & -j)
27                 res += a[i][j];
28         return res;
29     }
30     void update(int x1, int y1, int x2, int y2)
31     {
32         update(x1 - 1, y1 - 1, 1);
33         update(x1 - 1, y2, -1);
34         update(x2, y1 - 1, -1);
35         update(x2, y2, 1);
36     }
37 }
38 
39 int main()
40 {
41     inv[1] = 1;
42     for (int i = 2; i < N; ++i) inv[i] = inv[p % i] * (p - p / i) % p; 
43     while (scanf("%d%d%d", &n, &m, &q) != EOF)
44     {
45         memset(ans, 0, sizeof ans); BIT::init(); 
46         for (int i = 1, l, r; i <= n; ++i)
47         {
48             scanf("%d%d", &l, &r);
49             for (int j = l; j <= r; ++j) 
50                 ans[i][j] = 2ll * (j - l + 1) %p * (r - j + 1) %p * inv[r - l + 1] % p * inv[r - l + 2] % p; 
51             //cout << ans[i][l] * (r - l + 1) * (r - l + 2) / 2 % p << endl;
52         }
53         for (int qq = 1; qq <= q; ++qq)
54         {
55             int x1, x2, y1, y2;
56             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
57             BIT::update(x1, y1, x2, y2);
58         }    
59         ll res = 0;
60         for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (!BIT::query(i, j))
61         {
62             //cout << i << " " << j << endl;
63             res = (res + ans[i][j]) % p;
64         }
65         printf("%lld\n", res);
66     }
67     return 0;
68 }
View Code

I:石头剪刀布

Solved.

思路:

考虑有$x之前要被a个人挑战,要挑战b个人$

那么$此时对于x满足的方案数是3^n \cdot \frac{1}{3}^b \cdot \frac{2}{3}^a$

然后考虑怎么维护$a和b$

我们发现对于1操作

我们将$y 接在 x 下面的话,这样最后会构成一棵树$

那么$b就是祖宗的个数$

再考虑$a是什么,我们发现其实就是 它的所有祖先当中 所有比它后加入的儿子个数 以及它所有的儿子个数$

然后再发现一棵子树对其他点的影响,发现受影响的点就是它的父亲中比它先来的儿子中所对应的所有子树

这一段在$DFS序中是连续的,线段树维护即可$

刚开始错误思路,写了个树剖,喵喵喵?

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 #define ll long long
  5 #define N 200010
  6 const ll MOD = (ll)998244353;
  7 int n, m, fa[N];
  8 vector <int> G[N];
  9 struct qnode
 10 {
 11     int op, x, y;
 12     void scan()
 13     {
 14         scanf("%d%d", &op, &x); ++x;
 15         if (op == 1) 
 16         {
 17             scanf("%d", &y); ++y;
 18             fa[y] = x;
 19             G[x].push_back(y); 
 20         }
 21     }
 22 }q[N];
 23 
 24 int deep[N], sze[N], top[N], son[N], lp[N], rp[N], fp[N], cnt; 
 25 void DFS(int u)
 26 {
 27     sze[u] = 1;
 28     for (auto v : G[u]) if (v != fa[u])
 29     {
 30         deep[v] = deep[u] + 1;
 31         DFS(v);
 32         sze[u] += sze[v];
 33         if (!son[u] && sze[v] > sze[son[u]]) son[u] = v; 
 34     }
 35 }
 36 
 37 void getpos(int u, int sp)
 38 {
 39     top[u] = sp;
 40     lp[u] = ++cnt;
 41     fp[cnt] = u;
 42     if (!son[u])
 43     {
 44         rp[u] = cnt;
 45         return;
 46     }
 47     getpos(son[u], sp);
 48     for (auto v : G[u]) if (v != fa[u] && v != son[u])
 49         getpos(v, v);
 50     rp[u] = cnt;
 51 }
 52 
 53 namespace SEG
 54 {
 55     struct node
 56     {
 57         int v[2], lazy[2];
 58         node() {}
 59         void init()
 60         {
 61             memset(v, 0, sizeof v);
 62             memset(lazy, 0, sizeof lazy);
 63         }
 64         node operator + (const node &other) const
 65         {
 66             node res; res.init();
 67             for (int i = 0; i < 2; ++i) res.v[i] = v[i] + other.v[i];
 68             return res;
 69         }
 70     }a[N << 2], res;
 71     void build(int id, int l, int r)
 72     {
 73         a[id].init();
 74         if (l == r)
 75         {
 76             a[id].v[0] = deep[fp[l]];
 77             return;
 78         }
 79         int mid = (l + r) >> 1;
 80         build(id << 1, l, mid);
 81         build(id << 1 | 1, mid + 1, r);
 82     }
 83     void pushdown(int id)
 84     {
 85         for (int i = 0; i < 2; ++i) if (a[id].lazy[i])
 86         {
 87             int lazy = a[id].lazy[i];
 88             a[id].lazy[i] = 0;
 89             a[id << 1].v[i] += lazy;
 90             a[id << 1 | 1].v[i] += lazy;
 91             a[id << 1].lazy[i] += lazy;
 92             a[id << 1 | 1].lazy[i] += lazy;
 93         }
 94     }
 95     void update(int id, int l, int r, int ql, int qr, int v, int vis) 
 96     {
 97         if (l >= ql && r <= qr)
 98         {
 99             a[id].v[vis] += v;
100             a[id].lazy[vis] += v;
101             return;
102         }
103         int mid = (l + r) >> 1;
104         pushdown(id);
105         if (ql <= mid) update(id << 1, l, mid, ql, qr, v, vis);
106         if (qr > mid) update(id << 1 | 1, mid + 1, r, ql, qr, v, vis);
107     }
108     void query(int id, int l, int r, int pos)
109     {
110         if (l == r) 
111         {
112             res = a[id];
113             return;
114         }
115         int mid = (l + r) >> 1;
116         pushdown(id);
117         if (pos <= mid) query(id << 1, l, mid, pos);
118         else query(id << 1 | 1, mid + 1,r , pos);
119     }
120 }
121 
122 ll qmod(ll base, ll n)
123 {
124     ll res = 1;
125     while (n)
126     {
127         if (n & 1) res = (res * base) % MOD;
128         base = base * base % MOD;
129         n >>= 1;
130     }
131     return res;
132 }
133 ll ans[N];
134 
135 int main()
136 {    
137     while (scanf("%d%d", &n, &m) != EOF)
138     {
139         ++n;
140         for (int i = 1; i <= n; ++i) G[i].clear();
141         memset(fa, 0, sizeof fa);
142         memset(son, 0, sizeof son); cnt = 0;
143         for (int i = 1; i <= m; ++i) q[i].scan();
144         for (int i = 2; i <= n; ++i) if (!fa[i]) 
145         {
146             fa[i] = 1;
147             G[1].push_back(i); 
148         }
149         deep[1] = -1;
150         DFS(1); getpos(1, 1);
151         SEG::build(1, 1, n);
152         for (int i = 2; i <= n; ++i) if (fa[i] != 1)
153             SEG::update(1, 1, n, lp[fa[i]], lp[i] - 1, 1, 1);  
154         for (int i = m; i >= 1; --i)
155         {
156             if (q[i].op == 2)
157             {
158                 SEG::res.init();
159                 SEG::query(1, 1, n, lp[q[i].x]);
160                 int x = SEG::res.v[0], y = SEG::res.v[1];
161                 ans[i] = qmod(3, n - x - y - 1) * qmod(2, y) % MOD;
162             }
163             else
164             {    
165                 SEG::res.init(); 
166                 SEG::query(1, 1, n, lp[q[i].y]); 
167                 int x = SEG::res.v[0];
168                 SEG::update(1, 1, n, lp[q[i].y], rp[q[i].y], -x, 0);
169                 SEG::update(1, 1, n, lp[q[i].x], lp[q[i].y] - 1, -1, 1);
170             }
171         }
172         for (int i = 1; i <= m; ++i) if (q[i].op == 2) printf("%lld\n", ans[i]);
173     }
174     return 0;
175 }
View Code

猜你喜欢

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