【多校10】HDU 5407 5410 5411 5414 5416
来源:互联网 发布:电脑mac地址查询方法 编辑:程序博客网 时间:2024/06/10 23:28
- 最后一场多校,记录一下。。。
最近一个月听周的《晴天》听疯了。。单曲循环一千万次- -!
这场是朝鲜金策工业大学出的题,感受到了完全不同的画风。。有两点印象深刻
- 第一,题目描述不拖泥带水,非常清晰,可读性好,题目表述非常简洁。感觉就应该这样啊,,见过太多题目强行加入一个奇怪的故事背景,搞啥?自认为增加了趣味性,其实适得其反。。这一点真是值得学习。
- 第二,标程写得很棒,想说,这种风格调教出来的代码才是给别人看的好么–
HDU5407 CRB and Candies
- 求
LCM((n0),(n1)…(nn)) - 令以及
F(n)=LCM((n0),(n1)…(nn)) 则有G(n)=LCM(1,2,…n) 为啥捏?不造哇( ⊙o⊙ )。。。F(n)=G(n+1)n+1 显然
G(1)=1 ,考虑G(n) 的质因数分解形式,知道其中G(n)=⎧⎩⎨G(n−1),G(n−1)∗p,if n=pkif n!=pk p 表示一个质数,即判断n 是否能表达成某个质数的整数k 次方.最后的除以
n+1 部分需要用逆元处理一下
/* ********************************************** File Name: 5407.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年08月21日 星期五 09时06分16秒*********************************************** */#include <bits/stdc++.h>using namespace std;/* * let f(n)=lcm(C(n,0),...,C(n,n)), * g(n)=lcm(1,2,...,n). * Then f(n)=g(n+1)/(n+1).. * g(1)=1, * g(n)=g(n-1) if n != p^k, as p is a prime * =g(n-1)*p if n == p^k. */typedef long long ll;const int MOD = 1000000007;const int MAX = 1000002;int g[MAX] = {0};bool is_prime[MAX];//return: gcd(a, b).ll extgcd(ll a, ll b, ll& x, ll& y) { ll d = a; if (b) { d = extgcd(b, a % b, y, x); y -= (a / b) * x; } else { x = 1, y = 0; } return d;}ll mod_inverse(ll a, ll mod) { ll x, y; extgcd(a, mod, x, y); return (x % mod + mod) % mod;}int main() { memset(is_prime, true, sizeof(is_prime)); for (int i = 2; i <= MAX / i; ++i) { for (int j = i * i; j < MAX; j += i) { is_prime[j] = false; } } for (int i = 2; i < MAX; ++i) { if (is_prime[i]) { for (ll j = i; j < MAX; j *= i) { g[j] = i; } } } g[1] = 1; for (int i = 2; i < MAX; ++i) { if (g[i]) { g[i] = (ll)g[i] * g[i - 1] % MOD; } else { g[i] = g[i - 1]; } } /* for (int i = 1; i < 10; ++i) { printf("g[%d] = %d\n", i, g[i]); } */ int T; scanf(" %d", &T); while (T--) { int x; scanf(" %d", &x); printf("%d\n", (int)(((ll)g[x + 1] * mod_inverse(x + 1, MOD)) % MOD)); } return 0;}
HDU5410
- 买东西,拿糖
- 奇怪的背包,题解做了一些分析,然后搞啊搞,先排序什么的。。。
- 然而窝搞啊搞了好久,搞了一个更奇怪的多重背包
dp 。 - 将每种商品拆成
1,2,4,…,2k 组合,这是典型的多重背包做法,但是这个问题的特殊性是,比如在买了2 件该物品后,再买4 件该物品,得到的糖不再是2Ai+Bi 而是2Ai 。于是对拆完后的所有商品做dp 。考虑dp[i][j][0] 表示前i 件商品,花费j ,且不拿第i 件物品最多得到的糖;dp[i][j][1] 表示…拿了至少1 件第i 种物品最多能得到的糖。那么:dp[i][j][0]=max⎧⎩⎨dp[i−1][j][0 or 1],dp[i−1][j][0],如果 i是原来所属商品分解后的第一件如果 i不是上述第一件 dp[i][j][1]=max of⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪dp[i−1][j−w[i]][0 or 1]+Ai+Bi,dp[i−1][j−w[i]][0]+Ai+Bi,dp[i−1][j−w[i]][1]+Ai,如果i是原来所属商品分解后的第一件 如果 i不是上述第一件同上 - 简单分析一下,原来每件商品至多被拆成
log Wi 件,总共至多为nlog Wmax 件,总状态则为mnlogWmax 每次转移为O(1) 的,第一维空间可以优化掉,于是时间复杂度O(mnlogWmax) ,空间复杂度O(m) ,足够通过本题数据。
/* ********************************************** File Name: 5.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年08月20日 星期四 12时32分36秒*********************************************** */#include <bits/stdc++.h>using namespace std;const int MAX = 1024;struct Node { int w; int a; int b;};vector<Node> V;vector<int> pre;int W[MAX], A[MAX], B[MAX];int dp[MAX << 1][2];int n, m;int main() { int T; scanf(" %d", &T); while (T--) { scanf(" %d %d", &m, &n); V.clear(); pre.clear(); V.push_back((struct Node){0, 0}); pre.push_back(0); for (int i = 0; i < n; ++i) { scanf(" %d %d %d", W + i, A + i, B + i); /* gao */ Node tp; int k = 1; int idx = (int)V.size(); while (k * W[i] <= m) { tp.w = k * W[i]; tp.a = A[i] * k; tp.b = B[i]; //tp.c = A[i] * k + B[i]; V.push_back(tp); pre.push_back(idx); k <<= 1; } } memset(dp, 0, sizeof(dp)); for (int i = 1; i < (int)V.size(); ++i) { for (int j = m; j >= 0; --j) { //dp[j] = max(dp[j], dp[j - V[i].w] + V[i].c); //dp[i][j][0] = .. if (i == pre[i]) { dp[j][0] = max(dp[j][0], dp[j][1]); if (j >= V[i].w) { dp[j][1] = max(dp[j][1], max(dp[j - V[i].w][0], dp[j - V[i].w][1]) + V[i].a + V[i].b); } } else { if (j >= V[i].w) { dp[j][1] = max(dp[j][1], dp[j - V[i].w][0] + V[i].a + V[i].b); dp[j][1] = max(dp[j][1], dp[j - V[i].w][1] + V[i].a); } } } } int ans = max(dp[m][0], dp[m][1]); printf("%d\n", ans); } return 0;}
HDU5411
- 关系矩阵搞出来求和即可,构造出分块矩阵即可。题解构造出的矩阵为
(n+1)×(n+1) 我的是2n×2n ,简单优化一下才能通过。。
/* ********************************************** File Name: 5411.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年08月20日 星期四 18时11分09秒*********************************************** */#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MOD = 2015;const int MAX = 101;struct Mat { int n; int a[MAX][MAX]; Mat(int _n = 0, bool flag = false) { n = _n; memset(a, 0, sizeof(a)); if (flag) { for (int i = 0; i < n; ++i) { a[i][i] = 1; } } } Mat operator*(const Mat& b)const { Mat res(n); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (a[i][j] == 0) continue; for (int k = 0; k < n; ++k) { res.a[i][k] += a[i][j] * b.a[j][k]; if (res.a[i][k] >= MOD) { res.a[i][k] %= MOD; } } } } return res; }};Mat fast_pow(Mat a, int m) { Mat res(a.n, true); while (m) { if (m & 1) { res = res * a; } a = a * a; m >>= 1; } return res;}int main() { int T; scanf(" %d", &T); while (T--) { int n, m; scanf(" %d %d", &n, &m); Mat res(n << 1); for (int i = 1; i <= n; ++i) { int k, x; scanf(" %d", &k); while (k--) { scanf(" %d", &x); res.a[i - 1][x - 1] = 1; } } for (int i = n; i < (n << 1); ++i) { res.a[i - n][i] = 1; res.a[i][i] = 1; } res = fast_pow(res, m); /* for (int i = 0; i < res.n; ++i) { for (int j = 0; j < res.n; ++j) { printf("%d ", res.a[i][j]); } puts(""); } */ int sum = 1; for (int i = 0; i < n; ++i) { for (int j = n; j < (n << 1); ++j) { sum += res.a[i][j]; } } sum %= MOD; printf("%d\n", sum); } return 0;}
HDU5414
仔细分析后,只要满足
|s|≤|t| s 能匹配成t 的子序列- 设
t 前k 个字母连续相同,则s 前k 个也必须对应相同
就可以满足。唯一比较难想的是诸如
ale
如果添加到apple
,似乎需要往a 后面加2 个p 才能得到,但其实可以通过先加一个p ,然后再向a 后加1 个p ,就可以成功避开题目c!=d 的限制
/* ********************************************** File Name: 5414.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年08月21日 星期五 10时33分17秒*********************************************** */#include <bits/stdc++.h>using namespace std;const int MAX = 100007;char s[MAX], t[MAX];int main() { int T; scanf(" %d", &T); while (T--) { scanf(" %s %s", s, t); int len1 = strlen(s), len2 = strlen(t); if (len1 > len2 || s[0] != t[0]) { puts("No"); continue; } char c = t[0]; int k = 0; for (int i = 0; i < len2; ++i) { if (t[i] == c) ++k; else break; } for (int i = 0; i < len1; ++i) { if (s[i] == c) --k; else break; } if (k > 0) { puts("No"); continue; } int i = 0, j = 0; while (i < len1 && j < len2) { s[i] == t[j] ? (++i, ++j) : ++j; } puts(i == len1 ? "Yes" : "No"); } return 0;}
HDU5416
- 考虑到异或运算的特殊性质,设
1 为根,对子树中不经过根的路径,不妨假设路径上最高(设若每条边长为1,则此处高度即为到根距离)的一个点为u ,且路径由xu 和uy 两段组成,那么于是只需要预处理出val(xy)=val(xu)⊕val(uy)=0⊕val(ux)⊕val(uy)=(val(1u)⊕val(1u))⊕val(ux)⊕val(uy)=val(1x)⊕val(1y) 1 到各个点的路径异或值即可。统计的时候组合一下即可,另外f(u,v) 中u 可以等于v ,因此当Query 0 时要多注意一下。
/* ********************************************** File Name: 5416.cpp Auther: zhengdongjian@tju.edu.cn Created Time: 2015年08月21日 星期五 09时53分14秒*********************************************** */#include <bits/stdc++.h>using namespace std;typedef pair<int, int> P;typedef long long ll;const int MAX = 100007;const int MAX_VAL = MAX << 1;vector<P> G[MAX];bool vis[MAX];int cnt[MAX_VAL];void dfs(int u, int val) { vis[u] = true; if (u ^ 1) { ++cnt[val]; } for (auto it = G[u].begin(); it != G[u].end(); ++it) { if (vis[it->first]) continue; dfs(it->first, (it->second) ^ val); }}int main() { int T; scanf(" %d", &T); while (T--) { int n, q; scanf(" %d", &n); for (int i = 1; i <= n; ++i) { G[i].clear(); } int u, v, c; for (int i = 1; i < n; ++i) { scanf(" %d %d %d", &u, &v, &c); G[u].push_back(P(v, c)); G[v].push_back(P(u, c)); } memset(vis, false, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); dfs(1, 0); scanf(" %d", &q); while (q--) { scanf(" %d", &c); ll ans = 0LL; if (c == 0) { ans += n + cnt[0]; for (int i = 0; i < MAX_VAL; ++i) { ans += (ll)cnt[i] * (cnt[i] - 1) / 2; } } else { for (int i = 0; i < MAX_VAL; ++i) { ans += (ll)cnt[i] * (cnt[i ^ c]); } ans >>= 1; ans += cnt[c]; }#ifdef ONLINE_JUDGE#define lld I64d#endif printf("%lld\n", ans); } } return 0;}
0 0
- 【多校10】HDU 5407 5410 5411 5414 5416
- hdu-5407(多校2015)
- hdu-5416(多校2015)
- HDU 5414(2015多校10)-CRB and String(字符串处理)
- hdu 5411
- HDU 5414
- HDU 5407
- hdu 5416
- hdu 5410
- hdu 5410
- hdu 多校
- hdu 多校
- 多校 hdu
- 多校 hdu
- 多校 hdu
- HDU 多校
- 2016多校10 HDU 5857 Median
- 2016多校10 HDU 5858 Hard problem
- JDK API 在线文档
- C语言优先级总结
- 打开虚拟硬盘 失败
- 软键盘模式及对布局的影响
- 缓存穿透与缓存雪崩
- 【多校10】HDU 5407 5410 5411 5414 5416
- ionic localstorage使用例子
- 实现select自动选择下拉菜单的值
- Flume-ng+Kafka+Storm处理日志
- 枚举类型使用的最佳实践
- POJ 3279 Fliptile
- eclipse到Android Studio的项目迁移
- Eclipse生成的java class文件通过java命令行调用提示Exception in thread "main" java.lang.NoClassDefFoundError
- 启动Tomcat提示:指定的服务未安装