思路:记录每一个 A 、 B A、B A、B 的位置, B B B 的数量大于 k k k 则将多于的 B B B 的数量变为 A A A,反之同理。他是复制不是翻转,因此可以直接记录位置复制
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define sz size()
#define bpt __builtin_popcountll
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 2E6 + 10, mod = 998244353;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll ksm(int a, int k)
{
ll res = 1;
while (k)
{
if (k & 1)
{
res = (ll)res * a % mod;
}
k >>= 1;
a = (ll)a * a % mod;
}
return res;
}
ll fact[N], infact[N], inv[N];
void init()
{
fact[0] = fact[1] = infact[0] = infact[1] = inv[1] = 1;
for (int i = 2; i < N; i++)
{
fact[i] = ((ll)fact[i - 1] * i) % mod;
inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
infact[i] = (ll)infact[i - 1] * inv[i] % mod;
}
}
ll C(ll a, ll b)
{
if (a < b)
return 0;
return (ll)fact[a] * infact[b] % mod * infact[a - b] % mod;
}
const int MOD = 998244353;
map<int, int> mp1, mp2;
int f1 = 1, f2 = 1;
int c1 = 1, c2 = 1;
int p[N], vec[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n, k;
cin >> n >> k;
string s;
cin >> s;
vector<int> a, b;
for (int i = 0; i < n; i++)
{
if (s[i] == 'A')
a.push_back(i + 1);
else
b.push_back(i + 1);
}
if (b.size() == k)
{
puts("0");
}
else
{
puts("1");
if (k < b.size())
{
cout << b[b.size() - k - 1] << ' ' << 'A' << endl;
}
else
{
cout << a[k - b.size() - 1] << ' ' << 'B' << endl;
}
}
}
int main()
{
int _ = 1;
cin >> _;
while (_--)
solve();
}
思路 :观察发现,先修改前面会直接影响后面,因此为了保证后面的不受前面的影响,从后面开始;如果已经小于后面的数,则不用分裂; y = ( a i + x − 1 ) / x y = (a_i + x - 1) / x y=(ai+x−1)/x向上取整的方式,分裂 y − 1 y - 1 y−1 次,然后共有 y y y 个小于等于 a i / y a_i / y ai/y的数,更新 a I a_I aI;
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define sz size()
#define bpt __builtin_popcountll
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 2E6 + 10, mod = 998244353;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll ksm(int a, int k)
{
ll res = 1;
while (k)
{
if (k & 1)
{
res = (ll)res * a % mod;
}
k >>= 1;
a = (ll)a * a % mod;
}
return res;
}
ll fact[N], infact[N], inv[N];
void init()
{
fact[0] = fact[1] = infact[0] = infact[1] = inv[1] = 1;
for (int i = 2; i < N; i++)
{
fact[i] = ((ll)fact[i - 1] * i) % mod;
inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
infact[i] = (ll)infact[i - 1] * inv[i] % mod;
}
}
ll C(ll a, ll b)
{
if (a < b)
return 0;
return (ll)fact[a] * infact[b] % mod * infact[a - b] % mod;
}
const int MOD = 998244353;
map<int, int> mp1, mp2;
int f1 = 1, f2 = 1;
int c1 = 1, c2 = 1;
int p[N], vec[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void solve()
{
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
ll ans = 0;
for (int i = n - 2; i >= 0; i--)
{
if (a[i] <= a[i + 1])
continue;
int x = a[i + 1];
int y = (a[i] + x - 1) / x;
a[i] = a[i] / y; //
ans += y - 1;
}
cout << ans << endl;
}
int main()
{
int _ = 1;
cin >> _;
while (_--)
solve();
}
思路: k k k 显然不能小于最短路径 n + m − 2 n + m - 2 n+m−2,同时是二分图,因此 k k k 的奇偶性要与 n + m − 2 n + m - 2 n+m−2 相同,否则无解;将第一行和最后一列染色做基础路径,考虑 ( k − r e s ) m o d (k - res) mod (k−res)mod 4 4 4 的情况,不存在 1 1 1,奇偶不同不存在。
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define sz size()
#define bpt __builtin_popcountll
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 2E6 + 10, mod = 998244353;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll ksm(int a, int k)
{
ll res = 1;
while (k)
{
if (k & 1)
{
res = (ll)res * a % mod;
}
k >>= 1;
a = (ll)a * a % mod;
}
return res;
}
ll fact[N], infact[N], inv[N];
void init()
{
fact[0] = fact[1] = infact[0] = infact[1] = inv[1] = 1;
for (int i = 2; i < N; i++)
{
fact[i] = ((ll)fact[i - 1] * i) % mod;
inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
infact[i] = (ll)infact[i - 1] * inv[i] % mod;
}
}
ll C(ll a, ll b)
{
if (a < b)
return 0;
return (ll)fact[a] * infact[b] % mod * infact[a - b] % mod;
}
const int MOD = 998244353;
const int maxn = 30;
int d1[maxn][maxn], d2[maxn][maxn];
void solve()
{
int n, m, k;
cin >> n >> m >> k;
int res = n + m - 2;
if ((k - res) & 1 || res > k)
{
cout << "NO" << endl;
return;
}
puts("YES");
char s[2] = {'R', 'B'};
int cur = 0;
// 每一行的链接
for (int i = 0; i < n; i++)
{
for (int j = 1; j < m; j++)
{
d1[i][j] = (j & 1) ? cur : 1 - cur;
}
}
if (m % 2 == 0)
{
cur = 1;
}
// 每一列的链接
for (int i = 1; i < n; i++)
{
for (int j = 1; j <= m; j++)
{
d2[i][j] = (i & 1) ? cur : 1 - cur;
}
}
if (d1[0][2] == d2[1][1])
{ // 第一行第二条横边不同于第一行的第二竖边
d2[1][1] = d2[1][2] = 1 - d1[0][2];
}
if (d1[1][1] == d2[1][1])
{
d1[1][1] = 1 - d2[1][2];
}
if (d1[n - 1][m - 1] == d2[n - 1][m])//倒数两行的横与最后一行的竖不能相同
{
d1[n - 1][m - 1] = d1[n - 2][m - 1] = 1 - d2[n - 1][m];
}
for (int i = 0; i < n; i++)
{
for (int j = 1; j < m; j++)
{
cout << s[d1[i][j]] << ' ';
}
cout << endl;
}
for (int i = 1; i < n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << s[d2[i][j]] << ' ';
}
cout << endl;
}
}
int main()
{
int _ = 1;
cin >> _;
while (_--)
solve();
}
思路 :不超过一次的交换,那必然是最小的右端点和最大的左端点进行交换,这样交换后的值增大最多为 2 ∗ ( r − l ) 2 * (r - l) 2∗(r−l);将每个位置化作一条线段,能让结果增大的,是将不想交的线段变为相交。因此循环维护最小的右端点,遍历即可。
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define sz size()
#define bpt __builtin_popcountll
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int N = 2E6 + 10, mod = 998244353;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
const int MOD = 998244353;
const int maxn = 30;
int d1[maxn][maxn], d2[maxn][maxn];
void solve()
{
int n;
cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> b[i];
ll sum = 0;
for (int i = 0; i < n; i++)
{
sum += abs(a[i] - b[i]);
}
vector<pair<int, int>> p(n);
for (int i = 0; i < n; i++)
{
p[i] = minmax(a[i], b[i]);
}
sort(p.begin(), p.end());
int mx = 0, mn = 1e9;
int ml = 1e9;
for (int i = 0; i < n; i++) {
ml = min(ml, p[i].second);
}
for (int i = 0; i < n; i++) {
mx = max(mx, 2 * (p[i].first - ml));
}
cout << sum + mx << endl;
}
int main()
{
int _ = 1;
cin >> _;
while (_--)
solve();
}