A - 369
思路:分类讨论
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
void solve()
{
cin >> n >> m;
if(n == m) cout << 1 << edl;
else if(abs(n - m) % 2 == 1) cout << 2 << edl;
else cout << 3 << edl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}
B - Piano 3
思路:模拟
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
void solve()
{
char ch;
cin >> n;
ll sum1,sum2;
ll ans = 0;
sum1 = sum2 = -1;
for(int i = 1; i <= n; i ++ )
{
cin >> m >> ch;
if(ch == 'L')
{
if(sum1 != -1) ans += abs(sum1 - m);
sum1 = m;
}
else
{
if(sum2 != -1) ans += abs(sum2 - m);
sum2 = m;
}
}
cout << ans << edl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}
C - Count Arithmetic Subarrays
C - Count Arithmetic Subarrays
思路:双指针,维护以l为起点的等差数列最远到r,统计贡献
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
void solve()
{
cin >> n;
vector<ll>a(n + 1,0);
for(int i = 1; i <= n; i ++ ) cin >> a[i];
ll l = 1;
ll r = 1;
ll ans = 0;
while(l <= n)
{
while(a[l + 1] - a[l] == a[r + 1] - a[r] && r < n) r ++;
ans += r - l + 1;
l ++;
}
cout << ans << edl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}
D - Bonus EXP
https://atcoder.jp/contests/abc369/tasks/abc369_d
思路:dp,dp【i】【0】表示到第i个怪兽时,已经打了偶数个怪,dp【i】【1】同理
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
void solve()
{
cin >> n;
vector<ll>a(n + 1);
for(int i = 1; i <= n; i ++ ) cin >> a[i];
vector dp(n + 1,vector<ll>(2,0));
for(int i = 1; i <= n; i ++ )
{
dp[i][1] = max(dp[i - 1][1],dp[i - 1][0] + a[i]);
if(dp[i - 1][1]) dp[i][0] = dp[i - 1][1] + a[i] * 2;
dp[i][0] = max(dp[i - 1][0],dp[i][0]);
}
cout << max(dp[n][1],dp[n][0]) << edl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}
E - Sightseeing Tour
https://atcoder.jp/contests/abc369/tasks/abc369_e
思路:
状压dp+最短路预处理
发现点数较小,可使用n^3的最短路预处理。
发现他给与必须用的桥数量极小,考虑状态压缩dp即可
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
struct QWQ
{
ll u,v,w;
}a[N];
void solve()
{
cin >> n >> m;
vector dp(n + 1,vector<ll>(n + 1,1e17));
for(int i = 1; i <= m; i ++ )
{
cin >> a[i].u >> a[i].v >> a[i].w;
dp[a[i].u][a[i].v] = min(dp[a[i].u][a[i].v],a[i].w);
dp[a[i].v][a[i].u] = min(dp[a[i].v][a[i].u],a[i].w);
}
for(int k = 1; k <= n; k ++ )
{
for(int j = 1; j <= n; j ++ )
{
for(int i = 1; i <= n; i ++ )
{
if(i == j) dp[i][j] = 0;
else dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);
}
}
}
cin >> q;
while(q -- )
{
ll ans = LLONG_MAX;
ll k;
cin >> k;
vector<ll>b(k + 1);
for(int i = 1; i <= k; i ++ ) cin >> b[i];
vector an((1LL << k),vector<ll>(n + 1,1e17));
an[0][1] = 0;
for(int o = 0; o < (1LL << k); o ++ )
{
for(int i = 1; i <= k; i ++ )
{
auto [u,v,w] = a[b[i]];
if(o >> (i - 1) & 1)
{
for(int j = 1; j <= n; j ++ )
{
an[o][u] = min(an[o][u],an[o ^ (1 << (i - 1))][j] + dp[j][v] + w);
an[o][v] = min(an[o][v],an[o ^ (1 << (i - 1))][j] + dp[j][u] + w);
}
}
}
}
ll o = (1LL << k) - 1;
for(int i = 1; i <= n; i ++ ) ans = min(ans,an[o][i] + dp[i][n]);
cout << ans << edl;
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}
F - Gather Coins
思路:sort + 树状数组
个人感觉这题比E简单,读完题目你可以发现这题如果再加一个维度就是标准的三维偏序题,显然这里只是二维,因此连cdq都不用直接sort+树状数组即可。
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define edl '\n'
const int N = 1e6 + 10;
const int M = 1e3 + 10;
const int mod = 1e9 + 7;
ll n,m,q;
string s;
struct QWQ
{
ll x,y;
ll link;
ll sum;
}a[N];
bool cmp(QWQ A,QWQ B)
{
if(A.x != B.x) return A.x < B.x;
return A.y < B.y;
}
template <typename T>
struct Fenwick {
int n;
std::vector<T> a;
Fenwick(int n_ = 0) {
init(n_);
}
void init(int n_) {
n = n_;
a.assign(n, T{});
}
void add(int x, T v) {
for (int i = x + 1; i <= n; i += i & -i) {
if(v.first > a[i - 1].first) a[i - 1] = v;
}
}
//[0,x)
T sum(int x) {
T ans{};
for (int i = x; i > 0; i -= i & -i) {
if(a[i - 1].first > ans.first) ans = a[i - 1];
}
return ans;
}
};
Fenwick<pair<ll,ll>>f(N);
void solve()
{
cin >> n >> m >> q;
for(int i = 1; i <= q; i ++ )
{
cin >> a[i].x >> a[i].y;
a[i].sum = 1;
}
sort(a + 1, a + q + 1,cmp);
for(int i = 1; i <= q; i ++ ) a[i].link = i;
for(int i = 1; i <= q; i ++ )
{
pair<ll,ll> ok = f.sum(a[i].y + 1);
if(ok.first != 0)
{
a[i].link = ok.second;
a[i].sum = ok.first + 1;
}
f.add(a[i].y,{a[i].sum,i});
}
ll mm = 0;
ll ck = 0;
for(int i = 1; i <= q; i ++ )
{
if(mm < a[i].sum)
{
mm = a[i].sum;
ck = i;
}
}
vector<ll>ans;
ans.push_back(ck);
while(a[ck].link != ck)
{
ck = a[ck].link;
ans.push_back(ck);
}
cout << mm << edl;
ll xx,yy;
xx = yy = 1;
for(int i = ans.size() - 1; i >= 0; i -- )
{
int x = a[ans[i]].x;
int y = a[ans[i]].y;
ll sum = x - xx;
while(sum --) cout << 'D';
sum = y - yy;
while(sum --) cout << 'R';
xx = x;
yy = y;
}
ll sum = n - xx;
while(sum --) cout << 'D';
sum = m - yy;
while(sum --) cout << 'R';
cout << edl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
// cin >> t;
while(t -- ) solve();
return 0;
}