Weekly Challenges - Week 11

一拖再拖,忍无可忍,自己懒的没救了。

一周前就结束的比赛,到现在才想起来补。

最后一题貌似又遇到了splay。。。还是不会!!!shit

题目链接

A题--快速幂

 1 #include <cmath>

 2 #include <cstdio>

 3 #include <vector>

 4 #include <iostream>

 5 #include <algorithm>

 6 using namespace std;

 7 

 8 const int MOD = 1e9 + 7;

 9 

10 int mod_pow(int a, int b) {

11     int res = 1;

12     while (b) {

13         if (b & 1) res = (res * (long long)a) % MOD;

14         a = (a * (long long)a) % MOD;

15         b >>= 1;

16     }

17     return res;

18 }

19 

20 int main() {

21     /* Enter your code here. Read input from STDIN. Print output to STDOUT */   

22     int T;

23     ios::sync_with_stdio(false);

24     cin >> T;

25     while (T--) {

26         int t;

27         cin >> t;

28         cout << (2 + mod_pow(2, t + 1)) % MOD << endl;

29     }

30     return 0;

31 }

B题

如果说这题的困难之处,那就是要看出来其实这种数的个数很少。所以先把所有的范围之内的数打表出来。

 1 #include <cmath>

 2 #include <cstdio>

 3 #include <vector>

 4 #include <iostream>

 5 #include <algorithm>

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 #define rep(i, n) for (int i = (1); i <= (n); i++)

10 LL pw10[20];

11 const LL MAX_N = (LL)1e18;

12 

13 int main() {

14     pw10[0] = 1LL;

15     rep (i, 19) pw10[i] = pw10[i - 1] * 10;

16     vector<LL> ans;

17     rep (i, 9) ans.push_back(i);

18     int cur = 0, cur_len = 2, next = -1;

19     while (true) {

20         if (next == - 1 && ans[cur] * (cur_len + 1) >= pw10[cur_len]) {

21             next = cur;

22         }

23         LL x = ans[cur] * cur_len;

24         if (x >= MAX_N) break;

25         if (pw10[cur_len - 1] <= x && x < pw10[cur_len]) {

26             ans.push_back(x);

27         } else if (x >= pw10[cur_len]) {

28             cur = next;

29             next = -1;

30             cur_len++;

31             continue;

32         }

33         cur++;

34     }

35     //rep (i, 25) cerr << ans[i] << endl;

36     int T;

37     cin >> T;

38     while (T--) {

39         LL A, B;

40         cin >> A >> B;

41         LL rgt = upper_bound(ans.begin(), ans.end(), B) - ans.begin();

42         LL lft = lower_bound(ans.begin(), ans.end(), A) - ans.begin();

43         LL res = rgt - lft;

44         if (A == 0) res++;

45         cout << res << endl;

46     }

47     

48     return 0;

49 }

C题

题意:给出N个结点的树,每个结点有一个权值,在树上有一种操作,可以任选一个结点,然后删除以该结点为根的子树。最多执行K次这种操作

   使得树上的权值总和最大。

首先,如果按照前序遍历访问每个结点的顺序给结点做标记,那么以某个结点为根的子树中所有结点的标记一定该结点的后面。

dfs时顺便维护一下以每个结点为根的子树中结点的个数tot[i]。

dp[i][j]表示到dfs中第i个遍历的结点为止操作了j次可以获得的最大权值。

这样当到达第i个结点时,dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + value[i])   //不删除

            dp[i + tot[i]][j + 1] = max(dp[i + tot[i]][j + 1], dp[i][j]) //删除

 1 #include <cmath>

 2 #include <cstdio>

 3 #include <vector>

 4 #include <iostream>

 5 #include <algorithm>

 6 using namespace std;

 7 

 8 const int MAX_N = 100050;

 9 typedef long long LL;

10 const LL INF = (LL)1e19;

11 vector<int> G[MAX_N];

12 int w[MAX_N], vs[MAX_N], tot[MAX_N], cnt;

13 LL dp[MAX_N][205];

14 

15 void dfs(int u, int fa) {

16      int sz = (int)G[u].size();

17      vs[++cnt] = u;

18      tot[u] = 1;

19      if (sz == 1) {

20          return ;

21      }

22      for (int i = 0; i < sz; i++) {

23         int v = G[u][i];

24         if (v == fa) continue;

25         dfs(v, u);

26         tot[u] += tot[v];

27     }

28 }

29 

30 void read(int &res) {

31     res = 0;

32     int sign = 1;

33     char c = ' ';

34     while (c < '0' || c > '9') {

35         if (c == '-') sign = -1;

36         c = getchar();

37     }

38     while (c >= '0' && c <= '9') res = (res<<3) + (res<<1) + c - '0', c = getchar();

39     if (sign == -1) res = -res;

40 }

41 

42 int main() {

43     ios::sync_with_stdio(false);

44     int N, K;

45     cin >> N >> K;

46     //read(N); read(K);

47     for (int i = 1; i <= N; i++) cin >> w[i];//read(w[i]);

48     for (int i = 1; i <  N; i++) {

49         int u, v;

50         cin >> u >> v;

51         //read(u), read(v);

52         G[u].push_back(v);

53         G[v].push_back(u);

54     }

55     cnt = 0;

56     dfs(1, -1);

57     for (int i = 0; i <= K; i++) for (int j = 1; j <= N; j++) dp[j][i] = -INF;

58     //for (int i = 0; i <= K; i++) dp[0][i] = 0;

59     dp[1][0] = 0;

60     for (int i = 1; i <= N; i++) {

61         int u = vs[i];

62         for (int j = 0; j <= K; j++) if (dp[i][j] != -INF) {

63             dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + w[u]);

64             if (j < K)

65                 dp[i + tot[u]][j + 1] = max(dp[i + tot[u]][j + 1], dp[i][j]);

66         }

67     }

68     LL res = -INF;

69     for (int i = 0; i <= K; i++) res = max(res, dp[N + 1][i]);

70     cout << res << endl;

71     

72     return 0;

73 }

D题

题意:N种技能,第i种技能有ci个人学会,有T个巫师,每个巫师有两个集合A和B,他可以把一个拥有A集合中的技能的人转移到集合B中的某个技能中去。

问最多可以使多少个技能至少有一个人学会。

增加一个源点和汇点,源点到N种技能连一条容量为ci的边,从N种技能到汇点连一条容量为1的边。

对于每个巫师,从A集合中的技能连一条容量为1的边到该巫师,从该巫师连一条容量为1的边到B集合中的每种技能。

最大流即为答案。。。

  1 #include <queue>

  2 #include <cmath>

  3 #include <cstdio>

  4 #include <vector>

  5 #include <cstring>

  6 #include <iostream>

  7 #include <algorithm>

  8 using namespace std; 

  9 

 10 struct edge {

 11     int to, cap, rev;

 12     edge() {}

 13     edge(int _to, int _cap, int _rev):to(_to), cap(_cap), rev(_rev) {}

 14 };

 15 const int INF = 0x3f3f3f3f;

 16 const int MAX_V = 250; // ????`

 17 vector<edge> G[MAX_V]; // ?????

 18 int level[MAX_V]; // ??????????

 19 int iter[MAX_V];  // ????????????????

 20 int Q[MAX_V]; // BFS??

 21 

 22 void add_edge(int from, int to, int cap) {

 23     G[from].push_back(edge(to, cap, G[to].size()));

 24     G[to].push_back(edge(from, 0, G[from].size() - 1));

 25 }

 26 

 27 // ?????????????????

 28 void bfs(int s) {

 29     memset(level, -1, sizeof(level));

 30     int ini = 0, end = 0;

 31     Q[end++] = s;

 32     level[s] = 0; 

 33     while (end > ini) {

 34         int v = Q[ini++];

 35         for (int i = 0; i < G[v].size(); i++) {

 36             edge &e = G[v][i];

 37             if (e.cap > 0 && level[e.to] < 0) {

 38                 level[e.to] = level[v] + 1;

 39                 Q[end++] = e.to;

 40             }

 41         }

 42     }

 43 }

 44 

 45 // ??????????

 46 int dfs(int v, int t, int f) {

 47     if (v == t) return f;

 48     for (int &i = iter[v]; i < G[v].size(); i++) {

 49         edge &e = G[v][i];

 50         if (e.cap > 0 && level[v] < level[e.to]) {

 51             int d = dfs(e.to, t, min(f, e.cap));

 52             if (d > 0) {

 53                 e.cap -= d;

 54                 G[e.to][e.rev].cap += d;

 55                 return d;

 56             }

 57         }

 58     }

 59     return 0;

 60 }

 61 

 62 // ??????????

 63 int Dinic(int s, int t) {

 64     int flow = 0;

 65     for (;;) {

 66         bfs(s);

 67         if (level[t] < 0) return flow;

 68         memset(iter, 0, sizeof(iter));

 69         int f;

 70         while ((f = dfs(s, t, INF)) > 0) {

 71             flow += f;

 72         }

 73     }

 74 }

 75 

 76 int main() {

 77     ios_base::sync_with_stdio(false);

 78     

 79     int N, T;

 80     cin >> N >> T;

 81     int s = 0, t = N + T + 1;

 82     

 83     for (int i = 1; i <= N; i++) {

 84         int C;

 85         cin >> C;

 86         add_edge(s, i, C);

 87         add_edge(i, t, 1);

 88     }

 89     for (int i = 1; i <= T; i++) {

 90         int A, B;

 91         cin >> A;

 92         for (int j = 1; j <= A; j++) {

 93             int x;

 94             cin >> x;

 95             add_edge(x, N + i, 1);

 96         }

 97         cin >> B;

 98         for (int j = 1; j <= B; j++) {

 99             int x;

100             cin >> x;

101             add_edge(N + i, x, 1);

102         }

103     }

104     

105     cout << Dinic(s, t) << endl;

106     return 0;

107 }
  1 #include <queue>

  2 #include <cmath>

  3 #include <cstdio>

  4 #include <vector>

  5 #include <cstring>

  6 #include <iostream>

  7 #include <algorithm>

  8 using namespace std; 

  9 

 10 struct edge {

 11     int to, cap, rev;

 12     edge() {}

 13     edge(int _to, int _cap, int _rev):to(_to), cap(_cap), rev(_rev) {}

 14 };

 15 const int INF = 0x3f3f3f3f;

 16 const int MAX_V = 250; // ????`

 17 vector<edge> G[MAX_V]; // ?????

 18 int level[MAX_V]; // ??????????

 19 int iter[MAX_V];  // ????????????????

 20 int Q[MAX_V]; // BFS??

 21 

 22 void add_edge(int from, int to, int cap) {

 23     G[from].push_back(edge(to, cap, G[to].size()));

 24     G[to].push_back(edge(from, 0, G[from].size() - 1));

 25 }

 26 

 27 // ?????????????????

 28 void bfs(int s) {

 29     memset(level, -1, sizeof(level));

 30     int ini = 0, end = 0;

 31     Q[end++] = s;

 32     level[s] = 0; 

 33     while (end > ini) {

 34         int v = Q[ini++];

 35         for (int i = 0; i < G[v].size(); i++) {

 36             edge &e = G[v][i];

 37             if (e.cap > 0 && level[e.to] < 0) {

 38                 level[e.to] = level[v] + 1;

 39                 Q[end++] = e.to;

 40             }

 41         }

 42     }

 43 }

 44 

 45 // ??????????

 46 int dfs(int v, int t, int f) {

 47     if (v == t) return f;

 48     for (int &i = iter[v]; i < G[v].size(); i++) {

 49         edge &e = G[v][i];

 50         if (e.cap > 0 && level[v] < level[e.to]) {

 51             int d = dfs(e.to, t, min(f, e.cap));

 52             if (d > 0) {

 53                 e.cap -= d;

 54                 G[e.to][e.rev].cap += d;

 55                 return d;

 56             }

 57         }

 58     }

 59     return 0;

 60 }

 61 

 62 // ??????????

 63 int Dinic(int s, int t) {

 64     int flow = 0;

 65     for (;;) {

 66         bfs(s);

 67         if (level[t] < 0) return flow;

 68         memset(iter, 0, sizeof(iter));

 69         int f;

 70         while ((f = dfs(s, t, INF)) > 0) {

 71             flow += f;

 72         }

 73     }

 74 }

 75 

 76 int main() {

 77     ios_base::sync_with_stdio(false);

 78     

 79     int N, T;

 80     cin >> N >> T;

 81     int s = 0, t = N + T + 1;

 82     

 83     for (int i = 1; i <= N; i++) {

 84         int C;

 85         cin >> C;

 86         add_edge(s, i, C);

 87         add_edge(i, t, 1);

 88     }

 89     for (int i = 1; i <= T; i++) {

 90         int A, B;

 91         cin >> A;

 92         for (int j = 1; j <= A; j++) {

 93             int x;

 94             cin >> x;

 95             add_edge(x, N + i, 1);

 96         }

 97         cin >> B;

 98         for (int j = 1; j <= B; j++) {

 99             int x;

100             cin >> x;

101             add_edge(N + i, x, 1);

102         }

103     }

104     

105     cout << Dinic(s, t) << endl;

106     return 0;

107 }

E题

你可能感兴趣的:(HA)