题目链接
#include
#include
#include
using namespace std;
const int maxn = 100010;
typedef long long ll;
int N, trn, P, a[maxn], tr[maxn];
int lowbit(int x) {
return x & -x;
}
void add(int id, int c) {
for (int i = id; i <= trn; i += lowbit(i)) tr[i] += c;
}
int sum(int id) {
int res = 0;
for (int i = id; i; i -= lowbit(i)) {
res += tr[i];
}
return res;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &N);
trn = 0;
for (int i = 1; i <= N; i++) {
scanf("%d", &a[i]);
a[i]++;
trn = max(trn, a[i]);
}
ll ans = 0;
for (int i = 1; i <= N; i++) {
add(a[i], 1);
ans += i - sum(a[i]);
}
scanf("%d", &P);
ll res = ans;
memset(tr, 0, sizeof tr);
while(P--){
int l, r;
scanf("%d%d", &l, &r);
for (int i = l, k = 1; i <= r; i++, k++) {
add(a[i], 1);
res -= k - sum(a[i]);
}
//printf("*** %lld\n", res);
for (int i = l; i <= r; i++) add(a[i], -1);
swap(a[l], a[r]);
for (int i = l, k = 1; i <= r; i++, k++) {
add(a[i], 1);
res += k - sum(a[i]);
}
for (int i = l; i <= r; i++) add(a[i], -1);
ans = min(ans, res);
//printf("### %lld\n", res);
}
printf("%lld\n", ans);
}
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 100010;
int prime[maxn], mu[maxn], cnt, a[maxn], st[maxn];
vector<int> divisors[maxn];
void sieve(int N) {
mu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!st[i]) st[i] = prime[cnt++] = i, mu[i] = -1;
for (int j = 0; prime[j] <= N / i; j++) {
st[i * prime[j]] = prime[j];
if (i % prime[j] == 0) break;
mu[i * prime[j]] = -mu[i];
}
}
for (int i = 1; i <= N; i++) {
for (int j = i; j <= N; j += i) {
divisors[j].push_back(i);
}
}
}
int main() {
sieve(maxn - 1);
int T;
scanf("%d", &T);
while (T--) {
unordered_map<int, int> times;
unordered_map<int, ll> ans;
int N, M, K;
scanf("%d%d%d", &N, &M, &K);
for (int i = 1; i <= N; i++) {
scanf("%d", &a[i]);
for (auto p : divisors[a[i]]) {
times[p]++;
}
}
while (K--) {
int x;
scanf("%d", &x);
if (ans.count(x)) {
printf("%lld\n", ans[x]);
continue;
}
for (int i = 1; i * x <= M; i++) {
ll m = times[i * x];
ans[x] += (ll)mu[i] * m * m;
}
printf("%lld\n", ans[x]);
}
}
return 0;
}
#include
#include
#include
#include
using namespace std;
const int INF = 0x3f3f3f3f;
char str[5][5];
int dp[2][60000];
int Hash() {
int res = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int n = i * 3 + j, d;
if (str[i][j] == '.') d = 0;
else if (str[i][j] == 'O') d = 1;
else d = 2;
res += (int)(d * pow(3, n) + 0.5);
}
}
return res;
}
int cal() {
int res = 0;
for (int i = 0; i < 3; i++) {
if (str[i][0] == str[i][1] && str[i][1] == str[i][2]) {
if (str[i][0] == 'O') res++;
else res--;
}
}
for (int j = 0; j < 3; j++) {
if (str[0][j] == str[1][j] && str[1][j] == str[2][j]) {
if (str[0][j] == 'O') res++;
else res--;
}
}
if (str[0][0] == str[1][1] && str[1][1] == str[2][2]) {
if (str[0][0] == 'O') res++;
else res--;
}
if (str[0][2] == str[1][1] && str[1][1] == str[2][0]) {
if (str[0][2] == 'O') res++;
else res--;
}
return res;
}
//用记忆化搜索的方式优化
int dfs(int st, int opt, int cnt) {
if (dp[opt][st] != INF && dp[opt][st] != -INF) return dp[opt][st];
if (cnt == 0) {
return cal();
}
//printf("@@@ %d\n", opt);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (str[i][j] != '.') continue;
if (opt) {
str[i][j] = 'O';
//printf("### %s %s\n", str[0], str[1]);
int nst = Hash();
dp[opt][st] = max(dp[opt][st], dfs(nst, !opt, cnt - 1));
}
else {
str[i][j] = 'X';
//printf("*** %s %s\n", str[0], str[1]);
int nst = Hash();
dp[opt][st] = min(dp[opt][st], dfs(nst, !opt, cnt - 1));
//printf("!!! %d\n", dp[opt][st]);
}
str[i][j] = '.';
}
}
//printf("^^^ %d\n", dp[opt][st]);
return dp[opt][st];
}
int main() {
int T;
scanf("%d", &T);
int opt;
fill(dp[0], dp[0] + 60000, INF);
fill(dp[1], dp[1] + 60000, -INF);
while (T--) {
//这里的目的是做标记,看看那些没有算过
//但是要注意的是,opt = 0初始化为INF,opt = 1初始化为-INF
scanf("%d", &opt);
int cnt = 0;
for (int i = 0; i < 3; i++) {
scanf("%s", str[i]);
for (int j = 0; j < 3; j++) cnt += (str[i][j] == '.');
}
printf("%d\n", dfs(Hash(), opt, cnt));
}
return 0;
}