Codeforces Educational Round 5 ABCDE
2016-01-16 13:23
471 查看
套题链接:http://codeforces.com/contest/616
难度类型:难度上有错位,个人觉得B比A简单,D比C简单,E是数论。BD的代码量较少,AC较多。
大数的比较,一开始Java大数乱搞TLE了。
然后反正就改成手写的比较,前导零忽略掉然后比长度,比字典序。
每行最小值的最大值,读懂题就行了。
主流做法是搜索处理答案或用并查集合并来处理,要算的就是每个空的点的连通块大小。
我用了并查集,做答案的话就是对每个占位的点将四周的点再和它合并,我用set来做这个,因为直接在并查集里面合并会影响到并查集的结构。
数据只有六次方,非法存在传递性,因此尺取法乱搞就行了。
维护一个数组cnticnt_i表示值为ii的数当前有多少个。
移动右边的指针,找左边的最优解,同时维护cntcnt数组具体可以参照代码或者《挑战》。
求(∑i=1mnmodi)mod109+7(\sum\limits_{i=1}^{m}{n \mod i}) \mod 10^9+7
由于main函数一处乘法没有对nn取模,非常可惜没能在场上A掉,赛后五分钟一下就看到了。
具体的做法就是说分块,算等差,复杂度是对数的。此题很适合暴力对拍。
具体推导过程可看我另一篇:[b]/article/8670588.html
难度类型:难度上有错位,个人觉得B比A简单,D比C简单,E是数论。BD的代码量较少,AC较多。
A
题解
类型:大数,模拟大数的比较,一开始Java大数乱搞TLE了。
然后反正就改成手写的比较,前导零忽略掉然后比长度,比字典序。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 1e6+5; char a ; char b ; int main() { gets(a); gets(b); char *sa = a, *sb = b; while (*sa == '0') sa++; while (*sb == '0') sb++; int la = strlen(sa), lb = strlen(sb); if (la != lb) { puts(la < lb ? "<" : ">"); return 0; } int val = strcmp(sa, sb); if (val < 0) { puts("<"); } else if (val == 0) { puts("="); } else { puts(">"); } return 0; }
B
题解
类型:模拟每行最小值的最大值,读懂题就行了。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head int main() { int n, m, x, ans = 0; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { int mn = 1e9+5; for (int j = 0; j < m; j++) { scanf("%d", &x); mn = min(mn, x); } ans = max(ans, mn); } printf("%d\n", ans); return 0; }
C
题解
类型:并查集/搜索主流做法是搜索处理答案或用并查集合并来处理,要算的就是每个空的点的连通块大小。
我用了并查集,做答案的话就是对每个占位的点将四周的点再和它合并,我用set来做这个,因为直接在并查集里面合并会影响到并查集的结构。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 1000+5; const int M = 1000000+5; int fa[M]; int cnt[M]; char s ; int pos ; int res ; int find(int key) { return (key == fa[key]) ? key : (fa[key] = find(fa[key])); } void init(int n) { for (int i = 1; i <= n; i++) { fa[i] = i; cnt[i] = 1; } } void joint(int u, int v) { int a = find(u), b = find(v); if (a != b) { fa[a] = b; cnt += cnt[a]; } } bool same(int u, int v) { return find(u) == find(v); } int dx[4] = {0, 0, 1, -1}; int dy[4] = {1, -1, 0, 0}; int n, m; PII mov(PII &cur, int dir) { return mp(cur.fi+dx[dir], cur.se+dy[dir]); } bool isok(PII &cur) { return cur.fi > 0 && cur.fi <= n && cur.se > 0 && cur.se <= m; } int main() { scanf("%d%d", &n, &m); init(n*m); for (int i = 1; i <= n; i++) { scanf("%s", s[i]+1); for (int j = 1; j <= m; j++) { pos[i][j] = (i-1)*m+j; } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (s[i][j] == '*') continue; for (int dir = 0; dir < 4; dir++) { PII to = mp(i+dx[dir], j+dy[dir]); if (!isok(to) || s[to.fi][to.se] == '*') continue; joint(pos[i][j], pos[to.fi][to.se]); } } } set<int> se; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (s[i][j] != '*') continue; int ans = 1; for (int dir = 0; dir < 4; dir++) { PII to = mp(i+dx[dir], j+dy[dir]); if (!isok(to) || s[to.fi][to.se] == '*') continue; int temp = find(pos[to.fi][to.se]); if (se.find(temp) == se.end()) { ans += cnt[temp]; se.insert(temp); } } res[i][j] = ans % 10; se.clear(); } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { putchar((s[i][j] == '*') ? '0' + res[i][j] : '.'); } puts(""); } return 0; }
D
题解
类型:模拟,数据维护,尺取法数据只有六次方,非法存在传递性,因此尺取法乱搞就行了。
维护一个数组cnticnt_i表示值为ii的数当前有多少个。
移动右边的指针,找左边的最优解,同时维护cntcnt数组具体可以参照代码或者《挑战》。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const int N = 1e6+5; int a ; int cnt ; int main() { int k, n; int ansl, ansr, ans = 0; int l = 1, cur = 0; scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", a+i); if (cnt[a[i]]++ == 0) cur++; while (cur > k) { if (cnt[a[l]]-- == 1) cur--; l++; } if (i-l+1 > ans) { ansl = l, ansr = i, ans = i-l+1; } } printf("%d %d\n", ansl, ansr); return 0; }
E
题解
类型:数论求(∑i=1mnmodi)mod109+7(\sum\limits_{i=1}^{m}{n \mod i}) \mod 10^9+7
由于main函数一处乘法没有对nn取模,非常可惜没能在场上A掉,赛后五分钟一下就看到了。
具体的做法就是说分块,算等差,复杂度是对数的。此题很适合暴力对拍。
具体推导过程可看我另一篇:[b]/article/8670588.html
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <queue> #include <string> #include <vector> #include <set> #include <map> #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define sz(x) ((int)(x).size()) #define fi first #define se second using namespace std; typedef long long LL; typedef vector<int> VI; typedef pair<int,int> PII; LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;} // head const LL MOD = 1e9+7; LL ck(LL n, LL m) { LL ans = 0; for (int i = 1; i <= m; i++) { ans += (n%i); ans %= MOD; } return ans; } LL solve(LL n, LL m) { LL be = 1, en, mul, ans = 0; while (be <= m) { mul = n/be; en = min(n/mul, m); LL cur = n%be; LL num = (MOD+en-be)%MOD; ans += (MOD + cur + cur-num*mul%MOD) % MOD * (num+1) % MOD; ans %= MOD; be = en+1; } return ans * powmod(2, MOD-2, MOD) % MOD; } int main() { LL n, m; scanf("%I64d%I64d", &n, &m); LL ans = 0; if (m > n) { ans = (MOD+m-n)%MOD * (n%MOD) % MOD; } ans = ans+solve(n, min(m, n)); printf("%I64d\n", ans%MOD); return 0; }
相关文章推荐
- hbase1.1.2安装
- 【Java】判断字符串是否为数字的方法
- IOPS
- hbase1.1.2安装
- C#精确计算算法运行时间
- Shell脚本的执行方式-50
- Objective-C UI之UITableView详解
- CGAffineTransformMakeRotation 实现旋转
- CSS实现网页“回到顶部”的效果代码
- 用GitLab搭建自己的私有GitHub
- LeetCode-50-Pow(x, n)( 二分法)-Medium
- java组装json和提取一个json的例子
- 用GitLab搭建自己的私有GitHub
- jquery中奖实例代码
- poj1008 Maya Calendar
- listview刷新
- CentOS 7防火墙服务FirewallD指南
- linux下arm-linux-gcc安装配置
- sigsetjmp,siglongjmp的使用
- Pycharm专业版注册