A. Maximize?
枚举1->x的数字:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int N = 2e5+10;
int mod = 1e9+7;
int P = 13331;
int x;
int gcd(int x, int y)
{
if (x % y == 0) return y;
return gcd(y,x%y);
}
void solve()
{
cin >> x;
int ma = 0;
int ans = 0;
for (int i = 1;i < x;i++)
{
if (ma < gcd(i,x)+i)
{
ma = gcd(i,x)+i;
ans = i;
}
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
B. Prefiquence
双指针跑一遍:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int N = 3e5+10;
int mod = 1e9+7;
int P = 13331;
int n, m;
void solve()
{
cin >> n >> m;
string A, B;
cin >> A >> B;
int len1 = A.length();
int len2 = B.length();
int ans = 0;
for (int i = 0, j = 0;i < len1,j < len2;j++)
{
if (A[i] == B[j])
{
i++;
ans++;
}
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
C. Assembly via Remainders
要保证B[i] > A[i+1],而且B[i] % B[i-1] == A[i],定义B[1] = 1, 剩下枚举:
#include <bits/stdc++.h>
using namespace std;
#define inf 1e18
typedef long long LL;
typedef unsigned long long ULL;
const int N = 2e5+10;
int mod = 1e9+7;
int P = 13331;
int n, A[N];
LL B[N];
void solve()
{
cin >> n;
for (int i = 2;i <= n;i++) cin >> A[i];
A[n+1] = 1;
B[1] = A[2]+1;
for (int i = 2;i <= n;i++)
{
for (int j = 1;;j++)
{
if (B[i-1]*j+A[i]>A[i+1])
{
B[i] = B[i-1]*j+A[i];
break;
}
}
}
for (int i = 1;i <= n;i++)
{
if (i > 1) cout << " ";
cout << B[i];
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D. Permutation Game
当这个人已经到达在他能抵达的最大值后,便没有意义再移动,遍历这个人能到达最大之前,考虑继续移动和不再移动,保存最大值:
#include <bits/stdc++.h>
using namespace std;
#define inf 1e18
typedef long long LL;
typedef unsigned long long ULL;
const int N = 2e5+10;
int mod = 1e9+7;
int P = 13331;
int n, k, ps, pb;
int p[N], A[N], vis[N];
LL max(LL a, LL b)
{
if (a > b) return a;
return b;
}
void solve()
{
cin >> n >> k >> ps >> pb;
int ma = 0, u = 0;
for (int i = 1;i <= n;i++) cin >> p[i];
for (int i = 1;i <= n;i++)
{
cin >> A[i];
}
int ma1 = 0, ma2 = 0;
int num1 = 0, num2 = 0;
int st = ps;
memset(vis,0,sizeof(vis));
int xx = 0;
while (vis[st] == 0&&xx < k)
{
vis[st] = 1;
if (A[st] > ma1)
{
ma1 = A[st];
}
st = p[st];
xx++;
}
memset(vis,0,sizeof(vis));
st = pb;
int yy = 0;
while (vis[st] == 0&&yy < k)
{
vis[st] = 1;
if (A[st] > ma2)
{
ma2 = A[st];
}
st = p[st];
yy++;
}
st = ps;
// cout << ma1 << "=====" << ma2 << endl;
while (A[st] != ma1)
{
st = p[st];
num1++;
}
st = pb;
while (A[st] != ma2)
{
st = p[st];
num2++;
}
// cout << num1 << "=====" << num2 << endl;
LL ans1 = 0, ans2 = 0, QQ = 0, WW = 0;
st = ps;
int op = 0;
while (1)
{
ans1 = max(ans1,(LL)(k-op)*A[st]+QQ);
QQ += A[st];
op++;
if (A[st] == ma1) break;
st = p[st];
}
st = pb;
op = 0;
while (1)
{
ans2 = max(ans2,(LL)(k-op)*A[st]+WW);
WW += A[st];
op++;
if (A[st] == ma2) break;
st = p[st];
}
st = pb;
// cout << ans1 << "====" << ans2 << endl;
if (ans1 > ans2) cout << "Bodya" << endl;
if (ans1 < ans2) cout << "Sasha" << endl;
if (ans1 == ans2) cout << "Draw" << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
E. Cells Arrangement
容易得出大小为n*n的距离集合为{0,1,2......(2*n-1)},瞎构造一下出来了:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int N = 3e5+10;
int mod = 1e9+7;
int P = 13331;
int n;
void solve()
{
cin >> n;
for (int i = 1;i <= n-2;i++)
{
cout << i << " " << i << endl;
}
cout << n << " " << n-1 << endl;
cout << n << " " << n << endl << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
F. Equal XOR Segments
利用前缀存一下区间异或和,当k > 3时可以转化为k == 3的情况 ,k == 2时:找到x满足A[l-1] ^ A[x] == A[x] ^ A[r],即A[l-1] == A[r],k == 3时:找到x, y满足A[l-1] ^ A[x] == A[x] ^ A[y] == A[y] ^ A[r],即A[l-1] == A[y],A[x] == A[r], x < y :
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int N = 2e5+10;
int mod = 1e9+7;
int P = 13331;
int n, q, A[N];
void solve()
{
cin >> n >> q;
map<int,vector<int>> id;
id[0].push_back(0);
for (int i = 1;i <= n;i++)
{
cin >> A[i];
A[i] ^= A[i-1];
id[A[i]].push_back(i);
}
while (q--)
{
int l, r;
cin >> l >> r;
if (A[r] == A[l-1])
{
cout << "YES" << endl;
continue;
}
int ll = *--lower_bound(id[A[l-1]].begin(),id[A[l-1]].end(),r);
int rr = *lower_bound(id[A[r]].begin(),id[A[r]].end(),l);
if (ll > rr) cout << "YES" << endl;
else cout << "NO" << endl;
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
G1. Division + LCP (easy version)
二分答案,判断是否有大于等于l个子串,(本题字符串哈希好像G了),用Z函数:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
typedef unsigned long long ULL;
const int N = 3e5+10;
int mod = 1e9+7;
int P = 13331;
int n, k;
string A;
vector<int> z_function(string s)
{
int n = (int)s.length();
vector<int> z(n);
for (int i = 1, l = 0, r = 0; i < n; ++i)
{
if (i <= r && z[i - l] < r - i + 1)
{
z[i] = z[i - l];
}
else
{
z[i] = max(0, r - i + 1);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
}
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
}
return z;
}
bool check(int x,vector<int>&D)
{
int num = 1;
for (int i = x;i < n;)
{
if (D[i] >= x)
{
i += x;
num++;
}
else i++;
}
if (num >= k) return true;
return false;
}
void solve()
{
cin >> n >> k >> k;
cin >> A;
vector<int> D = z_function(A);
int l = 0, r = n+1;
while (l + 1 < r)
{
int mid = l + r >> 1;
if (check(mid,D)) l = mid;
else r = mid;
}
cout << l << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}