2017 Multi-University Training Contest - Team 3
2017-08-01 21:02
585 查看
1003
题意:给出n和k,然后给出n个数,求所有区间第k大数的和,区间长度小于k则是0
思路:参考了题解的思路,枚举第k大数是x,维护一个链表,链表里面全部是>=x的数,同时向左向右走k次,然后计算答案
虽然代码不长,但感觉其中很多东西都得想清楚
求答案过程实际上是要求左边0个比x大的,右边k - 1个比x大,然后左边1个比x大的,右边k - 2个比x大的,依次类推
1005
题意:给出n个点n - 1条边组成的树,每条边有权值,现在问你把2 3 ... n 这n - 1个点分成k部分,这k部分都是两两不相交的,然后在k部分中每一部分添加1这个点,然后求出每部分的最小生成树,要求k部分的最小生成树的权值和最大,求出这个值
思路:以1为根建树,算每一条边的贡献,如果这条边下面有x个结点,如果x >= k那么这条边会被算k次,否则就是x次,相当于把这些点放到不同的集合中去,这条边就可以多算几次
1008
思路:手算了几个猜了一下、结果就是求n^k
1011
签到
题意:给出n和k,然后给出n个数,求所有区间第k大数的和,区间长度小于k则是0
思路:参考了题解的思路,枚举第k大数是x,维护一个链表,链表里面全部是>=x的数,同时向左向右走k次,然后计算答案
虽然代码不长,但感觉其中很多东西都得想清楚
求答案过程实际上是要求左边0个比x大的,右边k - 1个比x大,然后左边1个比x大的,右边k - 2个比x大的,依次类推
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <ctime> #include <iostream> #include <algorithm> #include <sstream> #include <string> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <utility> using namespace std; #define LL long long #define pb push_back #define mk make_pair #define mst(a, b) memset(a, b, sizeof a) #define REP(i, x, n) for(int i = x; i <= n; ++i) const int MOD = 1e9 + 7; const int qq = 5e5 + 10; int pos[qq], pre[qq], suf[qq]; int x[105], y[105]; int a, b; int n, k; void Erase(int x) { int pp = pre[x]; int nn = suf[x]; if(pp) suf[pre[x]] = nn; if(nn <= n) pre[suf[x]] = pp; pre[x] = suf[x] = 0; } int main(){ int t; scanf("%d", &t); while(t--) { scanf("%d%d", &n, &k); for(int num, i = 1; i <= n; ++i) { scanf("%d", &num); pos[num] = i; } for(int i = 1; i <= n; ++i) { pre[i] = suf[i] = 0; } for(int i = 1; i <= n; ++i) { pre[i] = i - 1, suf[i] = i + 1; } LL ans = 0; for(int num = 1; num <= n - k + 1; ++num) { a = b = 0; int p = pos[num]; for(int d = p; d != 0 && a <= k + 1; d = pre[d]) x[++a] = d; for(int d = p; d != n + 1 && b <= k + 1; d = suf[d]) y[++b] = d; // printf("%d %d\n", a, b); x[++a] = 0; y[++b] = n + 1; for(int i = 1; i <= a - 1; ++i) { if(k + 1 - i >= 1 && k + 1 - i + 1 <= b){ ans += (LL)1LL * (x[i] - x[i + 1]) * (y[k + 1 - i + 1] - y[k + 1 - i]) * num; } } Erase(p); } printf("%lld\n", ans); } return 0; }
1005
题意:给出n个点n - 1条边组成的树,每条边有权值,现在问你把2 3 ... n 这n - 1个点分成k部分,这k部分都是两两不相交的,然后在k部分中每一部分添加1这个点,然后求出每部分的最小生成树,要求k部分的最小生成树的权值和最大,求出这个值
思路:以1为根建树,算每一条边的贡献,如果这条边下面有x个结点,如果x >= k那么这条边会被算k次,否则就是x次,相当于把这些点放到不同的集合中去,这条边就可以多算几次
#include <cstdio> #include <cstring> #include <cmath> #include <sstream> #include <iostream> #include <algorithm> #include <string> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <utility> using namespace std; #define LL long long #define pb push_back #define mk make_pair #define pill pair<int, int> #define ft first #define sd second #define mst(a, b) memset(a, b, sizeof a) #define REP(i, x, n) for(int i = x; i <= n; ++i) const int qq = 1e6 + 10; const int MOD = 1e9 + 7; LL num[qq]; vector<int> G[qq], dis[qq]; LL n, k; LL ans = 0; void Dfs(int u, LL dep, int fa) { int len = G[u].size(); for(int i = 0; i < len; ++i) { int v = G[u][i]; if(v == fa) continue; Dfs(v, dep + dis[u][i], u); if(num[v] >= k) ans += (LL)dis[u][i] * k; else ans += (LL)dis[u][i] * num[v]; num[u] += num[v]; } num[u] += 1; } void Init() { mst(num, 0); for(int i = 0; i <= n; ++i) { G[i].clear(), dis[i].clear(); } ans = 0; } int main(){ while(scanf("%lld%lld", &n, &k) != EOF) { Init(); for(int i = 1; i < n; ++i) { int x, y, z; scanf("%d%d%d", &x, &y, &z); G[x].pb(y), dis[x].pb(z); G[y].pb(x), dis[y].pb(z); } Dfs(1, 0, -1); printf("%lld\n", ans); } return 0; }
1008
思路:手算了几个猜了一下、结果就是求n^k
#include <cstdio> #include <cstring> #include <cmath> #include <sstream> #include <iostream> #include <algorithm> #include <string> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <utility> using namespace std; #define LL long long #define pb push_back #define mk make_pair #define pill pair<int, int> #define ft first #define sd second #define mst(a, b) memset(a, b, sizeof a) #define REP(i, x, n) for(int i = x; i <= n; ++i) const int qq = 1e5 + 10; const int MOD = 1e9 + 7; LL Solve(LL n, LL k) { LL ans = 1; while(k > 0) { if(k & 1) ans = (ans * n) % MOD; n = (n * n) % MOD; k >>= 1; } return ans; } int main(){ LL n, k; int Cas = 0; while(scanf("%lld%lld", &n, &k) != EOF) { n %= MOD; printf("Case #%d: %lld\n", ++Cas, Solve(n, k)); } return 0; }
1011
签到
#include <cstdio> #include <cstring> #include <cmath> #include <sstream> #include <iostream> #include <algorithm> #include <string> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <utility> using namespace std; #define LL long long #define pb push_back #define mk make_pair #define pill pair<int, int> #define ft first #define sd second #define mst(a, b) memset(a, b, sizeof a) #define REP(i, x, n) for(int i = x; i <= n; ++i) const int qq = 1e5 + 10; const int MOD = 998244353; int main(){ int t; scanf("%d", &t); int cnt = 0; while(t--) { int x; scanf("%d", &x); if(x <= 35) cnt++; } printf("%d\n", cnt); return 0; }
相关文章推荐
- 2017 Multi-University Training Contest - Team 3 hdu6060 RXD and dividing
- hdu 6058 Kanade's sum(链表)(2017 Multi-University Training Contest - Team 3 )
- hdu 6069 Counting Divisors(约数个数)(2017 Multi-University Training Contest - Team 4 )
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- HDU 6069 Counting Divisors(素数筛法+枚举+技巧)——2017 Multi-University Training Contest - Team 4
- hdu 6071 Lazy Running(优先队列+dijkstra)(2017 Multi-University Training Contest - Team 4)
- hdu 6073 Matching In Multiplication(2017 Multi-University Training Contest - Team 4 )
- 2017 Multi-University Training Contest - Team 5
- 2017 Multi-University Training Contest - Team 5 1008 【思维 + 01背包思想】
- 2017 Multi-University Training Contest - Team 6:1003&hdu6098、Inversion
- 2017 Multi-University Training Contest - Team 6 1008 Kirinriki【思维题 + 尺取】
- 2017 Multi-University Training Contest - Team 5:Rikka with Number
- HDU 6096 String(2017 Multi-University Training Contest - Team 6 1001)后缀自动机
- 2017 Multi-University Training Contest - Team 6: Kirinriki
- 2017 Multi-University Training Contest - Team 7 1010 Just do it
- HDU 6128 Inverse of sum(数论)——2017 Multi-University Training Contest - Team 7
- 2017 Multi-University Training Contest - Team 5 Rikka with Competition
- hdu 6170 dp 2017 Multi-University Training Contest - Team 9
- 2017 Multi-University Training Contest - Team 7 Hard challenge
- HDU-6178 Monkeys - 2017 Multi-University Training Contest - Team 10(树形DP)