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;
}