AtCoder Beginner Contest #179
My first ABC Solution
A:
给你一个英语单词,如果结尾字符为\(\tt s\),则结尾加上\(\tt es\),否则加上\(\tt s\)。
Code:
/*
Auth: Loxilante
Time: 2020/09/19
Prog: ABC179A
Lang: cpp
*/
#ifdef ONLINE_JUDGE
#pragma GCC optimize("O3")
#endif
#include <bits/extc++.h>
#define rep(i, l, r) for(int i = l; i < r; i++)
#define hrp(i, l, r) for(int i = l; i <= r; i++)
#define rev(i, r, l) for(int i = r; i >= l; i--)
#define ms(n, t) memset(n, t, sizeof(n))
#define pb push_back
#define int ll
#ifndef JOEON
#define D(...) 97
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename tn = int> inline tn next(void) { tn k; cin>>k; return k; }
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
string str = next<string>();
if (str[str.length()-1] == 's') str += "es";
else str += "s";
cout<<str<<endl;
return 0;
}
B:
给定\(n\),和\(n\)个长度为\(2\)的序列,若有\(3\)个连续的元素相等序列,则输出\(\tt {Yes}\),否则输出$ \tt {No}$。
Code:
/*
Auth: Loxilante
Time: 2020/09/19
Prog: ABC179B
Lang: cpp
*/
#ifdef ONLINE_JUDGE
#pragma GCC optimize("O3")
#endif
#include <bits/extc++.h>
#define rep(i, l, r) for(int i = l; i < r; i++)
#define hrp(i, l, r) for(int i = l; i <= r; i++)
#define rev(i, r, l) for(int i = r; i >= l; i--)
#define ms(n, t) memset(n, t, sizeof(n))
#define pb push_back
#define int ll
#ifndef JOEON
#define D(...) 97
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename tn = int> inline tn next(void) { tn k; cin>>k; return k; }
const int U = 105;
int a[U], b[U];
signed main(void)
{
int n = next(), ans = 0;
rep(i, 0, n) cin>>a[i]>>b[i];
rep(i, 0, n-2) if (a[i] == b[i] && a[i+1] == b[i+1] && a[i+2] == b[i+2])
{
cout<<"Yes"<<endl;
return 0;
}
cout<<"No"<<endl;
return 0;
}
C:
给\(n\),\(n = a*b+c (a, b, c \in \mathbb{N+})\),求\(a,b,c\)的对数。
想了一会儿,发现就是个简单bf,可以\(O(n)\)穷举\(a\)和\(b\),如果\(a*b < n\)则记入答案
Code:
/*
Auth: Loxilante
Time: 2020/09/19
Prog: ABC179C
Lang: cpp
*/
#ifdef ONLINE_JUDGE
#pragma GCC optimize("O3")
#endif
#include <bits/extc++.h>
#define rep(i, l, r) for(int i = l; i < r; i++)
#define hrp(i, l, r) for(int i = l; i <= r; i++)
#define rev(i, r, l) for(int i = r; i >= l; i--)
#define ms(n, t) memset(n, t, sizeof(n))
#define pb push_back
#define int ll
#ifndef JOEON
#define D(...) 97
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename tn = int> inline tn next(void) { tn k; cin>>k; return k; }
signed main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int n = next(), ans = 0;
hrp(i, 1, n)
{
int contin = 0;
hrp(j, 1, n)
{
if (i*j < n) ans++;
else {contin = 1; break;}
}
if (contin) continue;
}
return 0;
}
D:
给定\(n, k\),接下来\(k\)行有两个数\(a, b\),\([a, b] \in S\),你现在在一维坐标上的\(1\)点处,你每次只能向右走\(d(d \in S)\)格。现在你要到达\(n\),求方案数取模\({998244353}\)。
卡了我70min的题
由于vp过NOIP2018,我一眼就看出来这很像NOIP2018D1T2,是个线性dp。方程一眼就能看出来:
\(dp(i) = \sum _{j = 1} ^{|s|} dp(i-S[j])\)
Code:
/*
Auth: Loxilante
Time: 2020/09/19
Prog: D:O(n^2)
Lang: cpp
*/
#ifdef ONLINE_JUDGE
#pragma GCC optimize("O3")
#endif
#include <bits/extc++.h>
#define rep(i, l, r) for(int i = l; i < r; i++)
#define hrp(i, l, r) for(int i = l; i <= r; i++)
#define rev(i, r, l) for(int i = r; i >= l; i--)
#define ms(n, t) memset(n, t, sizeof(n))
#define pb push_back
#define int ll
#ifndef JOEON
#define D(...) 97
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename tn = int> inline tn next(void) { tn k; cin>>k; return k; }
int dp[22222222];
const int MOD = 998244353;
vector<int> seg;
signed main(void)
{
int n, k;
cin>>n>>k;
rep(i, 0, k)
{
int a, b;
cin>>a>>b;
hrp(j, a, b) seg.pb(j);
}
sort(seg.begin(), seg.end());
dp[1] = 1;
hrp(i, 1, n) rep(j, 0, seg.size()) if (i-seg[j] >= 1)
dp[i] += dp[i-seg[j]], dp[i] %= MOD;
cout<<dp[n]<<endl;
return 0;
}
但是这是不行哒,\(n <= 2*10^5,1 <= a,b <= n\)。如果用\(O(n^2)\)算法肯定会\(\tt{TLE}\)。
怎么优化呢?我开始也没什么头绪,不过一看输出,就恍然大悟楽。不难发现\(S\)中有\(k\)段相邻的数字,而我们要求的是它们之和,于是我们考虑查询区间和。
我们可以用前缀和(\(\rm \color{red}{PigeonGuGuGu}\))或树状数组或线段树来解决。
由于树状数组比线段树简单,模板还比较短,于是我选择树状数组。
接下来就是标准的树状数组木板了,修改点值,查询区间和,都是基操啦。
Code:
/*
Auth: Loxilante
Time: 2020/09/19
Prog: ABC179D
Lang: cpp
*/
#ifdef ONLINE_JUDGE
#pragma GCC optimize("O3")
#endif
#include <bits/extc++.h>
#define rep(i, l, r) for(int i = l; i < r; i++)
#define hrp(i, l, r) for(int i = l; i <= r; i++)
#define rev(i, r, l) for(int i = r; i >= l; i--)
#define ms(n, t) memset(n, t, sizeof(n))
#define pb push_back
#define int ll
#ifndef JOEON
#define D(...) 97
#endif
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
template<typename tn = int> inline tn next(void) { tn k; cin>>k; return k; }
int n,k,dp[22222222], seg1[15], seg2[15];
const int MOD = 998244353;
inline int lowbit(int k)
{
return k & -k;
}
inline void add(int x, int k)
{
while(x <= n)
{
dp[x] += k;
dp[x] %= MOD;
x += lowbit(x);
}
}
inline int su(int x)
{
int ans=0;
while(x != 0)
{
ans += dp[x];
ans %= MOD;
x -= lowbit(x);
}
return ans;
}
inline int sum(int a, int b)
{
return (su(b)-su(a-1)+2*MOD)%MOD;
}
signed main(void)
{
cin>>n>>k;
rep(i, 0, k) cin>>seg1[i]>>seg2[i];
add(1, 1);
hrp(i, 1, n) rep(j, 0, k)
{
int t = i-seg1[j], tt = i-seg2[j];
if (t <= 0) continue;
if (tt <= 0) tt = 1;
add(i, sum(tt, t));
}
cout<<sum(n, n)<<endl;
return 0;
}
E:
这场E切的人比D切的人还要多,然而我连题都没看懂
\(\rm \color{red}{PigeonGuGuGu}\)