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}\)

posted @ 2020-09-19 22:24  Loxilante  阅读(278)  评论(4编辑  收藏  举报