2017 Multi-University Training Contest
来源:互联网 发布:华星创业网络报销网址 编辑:程序博客网 时间:2024/06/06 07:53
1003
题意:d(i)为i的因子的个数,求区间[l, r] 所有d(i) l<=i <=r 的和
因子个数求法:传送门
思路:这样直接去求还是会TLE,所以我们用类似素数筛法进行区间筛来减少计算次数
每次在区间内找到第一个能整除素数p的,假设这个数是x,那么x + p 也是可以整除p的。就是普通的线性筛类似
#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 = 5e6 + 10;const LL MOD = 998244353;LL prime[qq], tot = 0;bool ispirme[qq];LL l, r, k;LL num[qq], ans[qq];void Init() { for(int i = 2; i < qq; ++i) { if(!ispirme[i]) { prime[++tot] = i; } for(int j = 1; j <= tot && (LL)i * prime[j] < qq; ++j) { ispirme[(LL)i * prime[j]] = true; if(i % prime[j] == 0) break; } }// printf("QQQ\n");}int main(){ Init(); int t; scanf("%d", &t); while(t--) { scanf("%lld%lld%lld", &l, &r, &k); for(LL i = l; i <= r; ++i) { num[i - l] = i; ans[i - l] = 1; }// printf("QQQ\n"); for(LL i = 1; i <= tot; ++i) { LL j = (l + prime[i] - 1LL) / prime[i] * prime[i];// printf("%lld\n", j);// if(r < prime[i]) break; while(j <= r) { LL p = 0; while(num[j - l] % prime[i] == 0) { p++; num[j - l] /= prime[i]; } ans[j - l] = (ans[j - l] * (p * k + 1LL)); if(ans[j - l] >= MOD) ans[j - l] %= MOD; j = j + prime[i];// printf("%lld\n", j); } } LL sum = 0; for(LL i = l; i <= r; ++i) { if(num[i - l] != 1) sum = sum + ans[i - l] * (k + 1LL); else sum = sum + ans[i - l]; if(sum >= MOD) sum %= MOD; } printf("%lld\n", sum); } return 0;}
1007
题意:给定二分图,求出图中所有完全匹配图的边权乘积的和,保证至少有一种完全匹配
思路:参考这位聚聚的代码 传送门
e[i] = e[i ^ 1] = 1 是标记了边。之前在想标记点为什么不行后来比对了两份标记边和点的代码发现
标记点访问顺序:8 16 9 18
标记边的访问顺序:8 16 9 18 8
感觉做一下处理标记点也是可以的,不过好像比较麻烦
#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 = 300000 + 10;const int MOD = 998244353;struct Edge {int nxt, to, w;bool mrk;}e[qq << 2];int T, n, head[qq << 1], cnt, deg[qq << 1], used[qq << 1];LL part[2];void Init() {mst(head, -1);mst(deg, 0);mst(used, 0);cnt = 0;}void AddEdge(int u, int v, int w) {e[cnt].nxt = head[u];e[cnt].to = v;e[cnt].w = w;e[cnt].mrk = 0;head[u] = cnt++;}void Dfs(int cur, int idx) {printf("%d ", cur);used[cur] = 1;for(int i = head[cur]; i != -1; i = e[i].nxt) {if(e[i].mrk)continue;e[i].mrk = e[i ^ 1].mrk = 1;(part[idx] *= e[i].w) %= MOD;Dfs(e[i].to, 1 - idx);}}int main(){scanf("%d", &T);while(T--) {scanf("%d", &n);Init();for(int u = 1, v, w; u <= n; ++u) {for(int j = 0; j < 2; ++j) {scanf("%d%d", &v, &w);AddEdge(u, v + n, w);AddEdge(v + n, u, w);deg[u]++, deg[v + n]++;}}LL ans = 1;queue<int> Q;for(int v = n + 1; v <= n + n; ++v) {if(deg[v] == 1) {Q.push(v);}}while(!Q.empty()) {int v = Q.front();Q.pop();used[v] = 1;for(int i = head[v]; i != -1; i = e[i].nxt) {if(e[i].mrk)continue;e[i].mrk = e[i ^ 1].mrk = 1;used[e[i].to] = 1;(ans *= e[i].w) %= MOD;for(int j = head[e[i].to]; j != -1; j = e[j].nxt) {e[j].mrk = e[j ^ 1].mrk = 1;deg[e[j].to]--;if(deg[e[j].to] == 1)Q.push(e[j].to);}}}printf("%lld\n", ans);for(int u = 1; u <= n; ++u) {if(used[u])continue;part[0] = part[1] = 1;Dfs(u, 0);puts("");printf("%lld %lld\n", part[0], part[1]);(ans *= (part[0] + part[1]) % MOD) %= MOD;}printf("%lld\n", ans);}return 0;}
1009
题意:给出n个数字,要你求m k,要求给出的n个数%m = k 的数字的个数要大于一半
思路:固定m = 2, 那么k只有两种情况0和1统计下等于1和等于0的情况,谁多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;int num[qq];int main(){ int t; scanf("%d", &t); while(t--) { int n; scanf("%d", &n); int a, b; a = b = 0; for(int x, i = 0; i < n; ++i) { scanf("%d", &x); if(x % 2 == 0) a++; else b++; } if(a > b) puts("2 0"); else puts("2 1"); } 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 = 1e9 + 7;char st[10][105], match[10][10];bool digit[10];int num[10][10];int ans[10];void Init() { mst(num, 0); num[0][4] = 1; num[1][1] = num[1][2] = num[1][4] = num[1][5] = num[1][7] = 1; num[2][2] = num[2][6] = 1; num[3][2] = num[3][5] = 1; num[4][1] = num[4][5] = num[4][7] = 1; num[5][3] = num[5][5] = 1; num[6][3] = 1; num[7][2] = num[7][4] = num[7][5] = num[7][7] = 1; num[9][5] = 1;}void Judge(int id) { for(int i = 0; i < 10; ++i) digit[i] = false; if(match[1][2] == 'X' && match[1][3] == 'X') { digit[1] = true; } if(match[2][1] == 'X' && match[3][1] == 'X') { digit[2] = true; } if(match[2][4] == 'X' && match[3][4] == 'X') { digit[3] = true; } if(match[4][2] == 'X' && match[4][3] == 'X') { digit[4] = true; } if(match[5][1] == 'X' && match[6][1] == 'X') { digit[5] = true; } if(match[5][4] == 'X' && match[6][4] == 'X') { digit[6] = true; } if(match[7][2] == 'X' && match[7][3] == 'X') { digit[7] = true; } for(int i = 0; i < 10; ++i) { bool f = true; for(int j = 1; j <= 7; ++j) { int a = num[i][j]; int b = (digit[j] == true ? 0 : 1); if(a != b) f = false; } if(f){ ans[id] = i; break; } } } int main(){ int t; scanf("%d", &t); Init(); while(t--) { for(int i = 1; i <= 7; ++i) { scanf("%s", st[i] + 1); } int x, y; x = y = 0; for(int i = 1; i <= 7; ++i) { ++x; y = 0; for(int j = 1; j <= 4; ++j) { ++y; match[x][y] = st[i][j]; } } Judge(1); x = y = 0; for(int i = 1; i <= 7; ++i) { ++x; y = 0; for(int j = 6; j <= 9; ++j) { ++y; match[x][y] = st[i][j]; } } Judge(2); x = y = 0; for(int i = 1; i <= 7; ++i) { ++x; y = 0; for(int j = 13; j <= 17; ++j) { ++y; match[x][y] = st[i][j]; } } Judge(3); x = y = 0; for(int i = 1; i <= 7; ++i) { ++x; y = 0; for(int j = 18; j <= 21; ++j) { ++y; match[x][y] = st[i][j]; } } Judge(4); for(int i = 1; i <= 4; ++i) { printf("%d", ans[i]); if(i == 2) printf(":"); } puts(""); } return 0;}
阅读全文
0 0
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- #2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- Mysql5.7学习总结
- 剑指offer:空格替换
- vue 多页面架子资料
- js json中如何删除指定元素
- JSON.parse() 和 JSON.stringify()
- 2017 Multi-University Training Contest
- 字典树
- openresty安装(MAC)
- 实现WebRTC的几个想法
- 一个人的旅行
- Longest Palindromic Substring
- HTML与xml的区别
- 安卓通过JDBC进行数据库操作
- kotlin Fragment 跳转到Activity