codeforces gym102040 前四题签到题解

Posted mooleetzi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces gym102040 前四题签到题解相关的知识,希望对你有一定的参考价值。

J

Description

 输入一个数,输出其1.15倍,保留两位小数

Solution

 read&write

 

E

 

Description

 给出两时间,计算其差值。

Solution

  模拟即可

 

C

 

Description

 给出一个$nleq100000$,求$n!的约数的约数个数$

Solution

  数论不会gcd,通过样例模拟了两遍,发现$4!=2^3*3$,素因子分开解决,$2^3时其因子有可能有2^0,2^1,2^2,2^3,而这些数的因子有4*2^0,3*2^1,2*2^2,1*2^3$

嗯?等差数列累加和!!$sum=1+2+3+4=(3+1)(3+2)/2$,那后面素因子3怎么搞,互不相干,分步计算法则,直接乘喽。

技术图片
  1 #include <algorithm>
  2 #include <cctype>
  3 #include <cmath>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cstring>
  7 #include <iostream>
  8 #include <map>
  9 #include <queue>
 10 #include <set>
 11 #include <stack>
 12 #if __cplusplus >= 201103L
 13 #include <unordered_map>
 14 #include <unordered_set>
 15 #endif
 16 #include <vector>
 17 #define lson rt << 1, l, mid
 18 #define rson rt << 1 | 1, mid + 1, r
 19 #define LONG_LONG_MAX 9223372036854775807LL
 20 #define ll LL
 21 using namespace std;
 22 typedef long long ll;
 23 typedef long double ld;
 24 typedef unsigned long long ull;
 25 typedef pair<int, int> P;
 26 int n, m, k;
 27 const int maxn = 1e6 + 10;
 28 const ll mod = 10000007;
 29 const ll inv2 = 7486194;
 30 template <class T>
 31 inline T read()
 32 {
 33     int f = 1;
 34     T ret = 0;
 35     char ch = getchar();
 36     while (!isdigit(ch))
 37     {
 38         if (ch == -)
 39             f = -1;
 40         ch = getchar();
 41     }
 42     while (isdigit(ch))
 43     {
 44         ret = (ret << 1) + (ret << 3) + ch - 0;
 45         ch = getchar();
 46     }
 47     ret *= f;
 48     return ret;
 49 }
 50 template <class T>
 51 inline void write(T n)
 52 {
 53     if (n < 0)
 54     {
 55         putchar(-);
 56         n = -n;
 57     }
 58     if (n >= 10)
 59     {
 60         write(n / 10);
 61     }
 62     putchar(n % 10 + 0);
 63 }
 64 template <class T>
 65 inline void writeln(const T &n)
 66 {
 67     write(n);
 68     puts("");
 69 }
 70 int vis[maxn], prime[maxn], pcnt, num[maxn];
 71 ll qpow(ll a, ll n)
 72 {
 73     ll res = 1;
 74     while (n)
 75     {
 76         if (n & 1)
 77             res = res * a % mod;
 78         a = a * a % mod;
 79         n >>= 1;
 80     }
 81     return res;
 82 }
 83 ll f(ll n, int p)//阶乘因子
 84 {
 85     if (n == 0)
 86         return 0;
 87     return f(n / p, p) + n / p;
 88 }
 89 void init()
 90 {
 91     for (int i = 2; i < maxn; i++)
 92     {
 93         if (!vis[i])
 94             prime[pcnt++] = i;
 95         for (int j = 0; j < pcnt && i * prime[j] <= maxn; j++)
 96         {
 97             vis[i * prime[j]] = 1;
 98             if (i % prime[j] == 0)
 99                 break;
100         }
101     }
102 }
103 
104 int main(int argc, char const *argv[])
105 {
106 #ifndef ONLINE_JUDGE
107     // freopen("in.txt", "r", stdin);
108     // freopen("out.txt", "w", stdout);
109 #endif
110     init();
111     while (~scanf("%d", &n) && n)
112     {
113         memset(num, 0, sizeof(int) * (n + 1));
114         for (int i = 2; i <= n; i++)
115             if (!vis[i])
116                 num[i] = f(n, i);
117         ll res = 1;
118         for (int i = 2; i <= n; i++)
119             if (num[i])
120             {
121                 if (num[i] & 1)
122                     res = res * ((num[i] + 1) >> 1) * (num[i] + 2) % mod;
123                 else
124                     res = res * ((num[i] + 2) >> 1) * (num[i] + 1) % mod;
125             }
126         writeln(res);
127     }
128     return 0;
129 }
View Code

 

F

 

Description

 给出一个n个点的树,$nleq10000$,m个查询,每次查询k条路径,问k条路径里的公共点个数

 

Solution

 树上路径,先整个树剖。emmm,公共点怎么求?每个点开一个set,最后set求交集,set_intersection,

写好交,wa2。你说超时我都能理解,wa算什么本事。debug了一个小时,还是一直wa,顶不住了,换思路。

我已经把路径存到了线段树里,那么每一条查询边进来的时候路径上的点权值+1,最后查询线段树里权值为k的点不就完了吗(其实想了很久)

每次查询完后清空当前查询加的权值,防止后续影响。

见代码

技术图片
  1 /*
  2     gym102040F 树剖+区间覆盖
  3 */
  4 #include <algorithm>
  5 #include <cctype>
  6 #include <cmath>
  7 #include <cstdio>
  8 #include <cstdlib>
  9 #include <cstring>
 10 #include <iostream>
 11 #include <map>
 12 #include <queue>
 13 #include <set>
 14 #include <stack>
 15 #if __cplusplus >= 201103L
 16 #include <unordered_map>
 17 #include <unordered_set>
 18 #endif
 19 #include <vector>
 20 #define lson rt << 1
 21 #define rson rt << 1 | 1
 22 #define LONG_LONG_MAX 9223372036854775807LL
 23 #define ll LL
 24 using namespace std;
 25 typedef long long ll;
 26 typedef long double ld;
 27 typedef unsigned long long ull;
 28 typedef pair<int, int> P;
 29 int n, m, k, mod;
 30 const int maxn = 1e5 + 10;
 31 template <class T>
 32 inline T read()
 33 {
 34     int f = 1;
 35     T ret = 0;
 36     char ch = getchar();
 37     while (!isdigit(ch))
 38     {
 39         if (ch == -)
 40             f = -1;
 41         ch = getchar();
 42     }
 43     while (isdigit(ch))
 44     {
 45         ret = (ret << 1) + (ret << 3) + ch - 0;
 46         ch = getchar();
 47     }
 48     ret *= f;
 49     return ret;
 50 }
 51 template <class T>
 52 inline void write(T n)
 53 {
 54     if (n < 0)
 55     {
 56         putchar(-);
 57         n = -n;
 58     }
 59     if (n >= 10)
 60     {
 61         write(n / 10);
 62     }
 63     putchar(n % 10 + 0);
 64 }
 65 template <class T>
 66 inline void writeln(const T &n)
 67 {
 68     write(n);
 69     puts("");
 70 }
 71 int dfn[maxn], head[maxn], siz[maxn], dep[maxn];
 72 int fa[maxn], top[maxn], a[maxn], son[maxn], w[maxn], cnt, tot, root;
 73 struct node
 74 {
 75     int to, nxt;
 76 } edg[maxn << 1];
 77 struct nodeT
 78 {
 79     int l, r;
 80     int lazy, minx, maxx;
 81 } tr[maxn << 2];
 82 inline void pushup(int rt)
 83 {
 84     tr[rt].maxx = max(tr[lson].maxx, tr[rson].maxx);
 85     tr[rt].minx = min(tr[lson].minx, tr[rson].minx);
 86 }
 87 inline void pushdown(int rt)
 88 {
 89     ll len = tr[rt].r - tr[rt].l + 1;
 90     if (tr[rt].lazy)
 91     {
 92         tr[lson].minx += tr[rt].lazy; //注意此题是区间加,固懒标记也应该是累加而不是覆盖
 93         tr[rson].maxx += tr[rt].lazy;
 94         tr[lson].maxx += tr[rt].lazy;
 95         tr[rson].minx += tr[rt].lazy;
 96         tr[lson].lazy += tr[rt].lazy;
 97         tr[rson].lazy += tr[rt].lazy;
 98         tr[rt].lazy = 0;
 99     }
100 }
101 void build(int rt, int l, int r)
102 {
103     tr[rt].l = l;
104     tr[rt].r = r;
105     tr[rt].lazy = 0;
106     tr[rt].maxx = tr[rt].minx = 0;
107     if (l == r)
108         return;
109     int mid = l + r >> 1;
110     build(lson, l, mid);
111     build(rson, mid + 1, r);
112 }
113 void modify(int rt, int L, int R, int v)
114 {
115     int l = tr[rt].l;
116     int r = tr[rt].r;
117     if (l >= L && r <= R)
118     {
119         tr[rt].lazy += v;
120         tr[rt].maxx += v;
121         tr[rt].minx += v;
122         return;
123     }
124     pushdown(rt); //当前区间没有在之前返回代表当前区间并非包含于待查询区间,在向左右区间查询时需要先将懒标记下放
125     int mid = l + r >> 1;
126     if (L <= mid)
127         modify(lson, L, R, v);
128     if (R > mid)
129         modify(rson, L, R, v);
130     pushup(rt); //更新父区间
131 }
132 int query(int rt, int L, int R, int k)
133 {
134     int l = tr[rt].l;
135     int r = tr[rt].r;
136     if (l >= L && r <= R && tr[rt].minx == tr[rt].maxx && tr[rt].minx == k)
137         return r - l + 1;
138     if (l > R || r < L || tr[rt].maxx < k)
139         return 0;
140     pushdown(rt); //和update同理
141     int mid = l + r >> 1;
142     int ans = 0;
143     if (L <= mid)
144         ans += query(lson, L, R, k);
145     if (R > mid)
146         ans += query(rson, L, R, k);
147     return ans;
148 }
149 void add(int x, int y)
150 {
151     edg[tot].nxt = head[x];
152     edg[tot].to = y;
153     head[x] = tot++;
154 }
155 void dfs1(int u, int p)
156 {
157     fa[u] = p;
158     dep[u] = dep[p] + 1;
159     siz[u] = 1;
160     int maxsz = -1;
161     for (int i = head[u]; ~i; i = edg[i].nxt)
162     {
163         int v = edg[i].to;
164         if (v == p)
165             continue;
166         dfs1(v, u);
167         siz[u] += siz[v];
168         if (siz[v] > maxsz)
169         {
170             maxsz = siz[v];
171             son[u] = v;
172         }
173     }
174 }
175 void dfs2(int u, int t)
176 {
177     dfn[u] = ++cnt;
178     top[u] = t;
179     w[cnt] = 0;
180     if (!son[u])
181         return;
182     dfs2(son[u], t);
183     for (int i = head[u]; ~i; i = edg[i].nxt)
184     {
185         int v = edg[i].to;
186         if (v == fa[u] || v == son[u])
187             continue;
188         dfs2(v, v);
189     }
190 }
191 inline void mchain(int x, int y, int z)
192 { //修改一条链
193     while (top[x] != top[y])
194     {
195         if (dep[top[x]] < dep[top[y]])
196             swap(x, y);
197         modify(1, dfn[top[x]], dfn[x], z);
198         x = fa[top[x]];
199     }
200     if (dep[x] > dep[y])
201         swap(x, y);
202     modify(1, dfn[x], dfn[y], z);
203 }
204 int main(int argc, char const *argv[])
205 {
206 #ifndef ONLINE_JUDGE
207     freopen("in.txt", "r", stdin);
208 #endif
209     int t = read<int>();
210     for (int cas = 1; cas <= t; cas++)
211     {
212         printf("Case %d:
", cas);
213         n = read<int>();
214         memset(head, -1, sizeof(int) * (n + 1));
215         memset(dfn, 0, sizeof(int) * (n + 1));
216         memset(son, 0, sizeof(int) * (n + 1));
217         memset(siz, 0, sizeof(int) * (n + 1));
218         memset(fa, 0, sizeof(int) * (n + 1));
219         memset(top, 0, sizeof(int) * (n + 1));
220         memset(dep, 0, sizeof(int) * (n + 1));
221         memset(w, 0, sizeof(int) * (n + 1));
222         tot = cnt = 0;
223         for (int i = 1; i < n; i++)
224         {
225             int x = read<int>(), y = read<int>();
226             add(x, y);
227             add(y, x);
228         }
229         dfs1(1, 0);
230         dfs2(1, 1);
231         build(1, 1, n);
232         m = read<int>();
233         while (m--)
234         {
235             int k = read<int>();
236             vector<P> cood;
237             cood.clear();
238             for (int j = 0; j < k; j++)
239                 cood.emplace_back(read<int>(), read<int>());
240             for (int j = 0; j < k; j++)
241                 mchain(cood[j].first, cood[j].second, 1);
242             writeln(query(1, 1, n, k));
243             for (int j = 0; j < k; j++)
244                 mchain(cood[j].first, cood[j].second, -1);
245         }
246     }
247     return 0;
248 }
View Code

 

 

 

 

以上是关于codeforces gym102040 前四题签到题解的主要内容,如果未能解决你的问题,请参考以下文章

E - Helping the HR Gym - 102040E

Gym102040 .Asia Dhaka Regional Contest(寒假自训第9场)

Codeforces Gym 100269 Dwarf Tower (最短路)

codeforces Gym 101063 C

codeforces Gym 100735 DEGHI

CodeForces Gym-101350M