A.
题意就是输入n,m,代表行含n格,列含m格,让我们在这个网格里面找线段,要求线段中点是交叉点;求有几个线段。
题解;
我们可以分析知道,把每一行每一列的含有合法的线段找出来,然后找出类似2*2,4*4的正方形的所有个数*2;
全部加起来就是答案。
#include <bits/stdc++.h>
using namespace std;
long long sum = 0, sum1 = 0, sum2 = 0;
int main() {
int n, m;
cin >> n >> m;
for (int i = 2; i <= n; i += 2) {
sum += n + 1 - i;
}
for (int i = 2; i <= m; i += 2) {
sum1 += m + 1 - i;
}
sum2 += sum * (m + 1) + sum1 * (n + 1);
for (int i = 1; i <= n; i++) {
sum2 += sum1 * (i / 2) * 2;
}
cout << sum2 << endl;
}
M.
题意就是给出a排列,b排列,我们的结果序列可以加ai,但是如果i>2,j>2;i^k=j,我们的结果就要减bj,求结果最大化。
我们可以用2,3,5……的的K次方来搞在每一个里面找到最大的数,然后加起来。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 7;
long long a[maxn], b[maxn], vis[maxn] = {0}, c[maxn], d[maxn];
int pd(int x, int y) {
for (ll i = x; i <= y; i *= x) {
if (i == y) {
return 1;
}
}
return 0;
}
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n; i++) {
cin >> b[i];
}
long long sum1 = 0;
ll maxn;
sum1 = a[1];
for (int i = 2; i <= n; i++) {
long long add = 0;
maxn = 0;
if (!vis[i]) {
for (ll j = i; j <= n; j *= i) {
c[add++] = j;
vis[j] = 1;
}
for (int g = 0; g < (1 << add); g++) {
ll add1 = 0;
long long sum = 0;
for (int h = 0; h < add; h++) {
if (g & (1 << h)) {
sum += a[c[h]];
d[add1++] = c[h];
}
}
for (int i = 0; i < add1; i++) {
for (int j = 0; j < add1; j++) {
if (d[i] < d[j] && pd(d[i], d[j])) {
sum -= b[d[j]];
}
}
}
maxn = max(maxn, sum);
}
}
sum1 += maxn;
}
cout << sum1 << endl;
}