2023河南萌新联赛第(二)场

发布时间 2023-09-25 00:29:23作者: chfychin

A. 自动收小麦机(循环并查集)

输入样例1

4 1 2
1 1 4 5
2 2 2 3
4

输出样例1

10

说明

在第4格放出水流后,水流会流向第3格,由于第3格高度比第4格低,所以水流继续向左流向第2格,因为平地水流只能流2格,所以到达第2格后水流停止,收获的小麦数量为1 + 4 + 5 = 10

输入2

5 2 2
1 1 4 5 1
2 2 3 3 4
4
3

输出2

9
6

点击查看代码
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 1e5 + 10;

int a[N], b[N], f[N], c[N];
int n, q, k, m, x, y, t;

unordered_map<int, int> mp;

int check(int x)
{
    int t = x, y = b[x];
    while(t)
    {
        t -= k;
        if(y != b[t])
        {
            t = mp[b[t]];
            y = b[t];
        }
        else break;
    }
    return max(t, 1ll);
}

void solve()
{
    cin >> n >> q >> k;
    for(int i = 1; i <= n; i ++)
    {
        cin >> a[i];
        f[i] = f[i - 1] + a[i];
    }
    for(int i = 1; i <= n; i ++)
        cin >> b[i], mp[b[i]] = i;
    k --;
    while(q --)
    {
        cin >> m;
        x = check(m);
        cout << f[m] - f[x - 1] << "\n";
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int T = 1;
    while(T --)
        solve();
    return T ^ T;
}

C. 悲伤的RT(RMQ+线性dp)

输入

5 2
3 1 5 7 9

输出

8

说明

RT可以将前三个树枝放在一个马车上,第四和第五个树枝放在另一个马车上。从第一个马车只能取出攻击力为1的树枝,第二个马车只能取出攻击力为7的树枝。取出树枝的攻击力之和最大为8。

点击查看代码
#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 10;
int a[N];
long long dp[N];
int f[N][32];
int n, c;
void RMQ()
{
    for(int j = 0; j < 25; j ++)
    {
        for(int i = 1; i + (1 << j) - 1 <= n; i ++)
            if(!j) f[i][j] = a[i];
            else f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
    }
}
int query(int l, int r)
{
    int len = r - l + 1;
    int k = log(len) / log(2);
    return min(f[l][k], f[r - (1 << k) + 1][k]);
}
int main()
{
    cin >> n >> c;
    for(int i = 1; i <= n; i ++) cin >> a[i];
    RMQ();
    for(int i = c; i <= n; i ++)
    {
        dp[i] = dp[i - 1];
        dp[i] = max(dp[i], dp[i - c] + query(i - c + 1, i));
    }
    long long res = 0;
    for(int i = c; i <= n; i ++) res = max(res, dp[i]);
    cout << res << '\n';
    return 0;
}

E. 释怀的RT(差分+前缀和)

输入1

5
0 1 0 0 10

输出1

4

说明

前四个方格被最后一个心岩照亮

输入2

5
0 1 0 0 1

输出2

3

说明

第一个方格和第三个方格被第二个格子的心岩照亮,第四个方格被第五个格子的心岩照亮,一共有三个格子被照亮

点击查看代码
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 1e6 + 10;

int a[N], b[N], c[N], n, m, ans, l, r, ll, rr;
struct node
{
    int l, r, id;
}p[N], t;
bool bk[N];

int cmp(node a, node b)
{
    return a.l < b.l;
}

void solve()
{
    cin >> n;
    l = 0, r = 0, ll = 0, rr = 0;
    int cnt = 0;
    for(int i = 1; i <= n; i ++)
    {
        cin >> a[i];
        if(a[i])
        {
            r = i - 1;
            l = max(1ll, i - a[i]);
            b[l] ++;
            b[r + 1] --;
            l = i + 1;
            r = min(n, a[i] + i);
            b[l] ++;
            b[r + 1] --;
        }
    }
    for(int i = 1; i <= n; i ++)
        b[i] += b[i - 1], ans += !!b[i];
    cout << ans << "\n";
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int T = 1;
    while(T --)
        solve();
    return T ^ T;
}

K. 卡特兰数(质因数分解)

输入

8

输出

2

说明

前8项卡特兰数之积为476150875200,末尾有两个连续的0

点击查看代码
#include<iostream>

using namespace std;

const int N = 5e6 + 10;

int f2[N], f5[N];

int f(int x, int y)
{
    int ans = 0;
    while(x % y == 0)
    {
        x /= y;
        ans ++;
    }
    return ans;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; i ++)
    {
        f2[i] = f2[i - 1];
        f5[i] = f5[i - 1];
        f2[i] += f(i * 4 - 2, 2);
        f5[i] += f(i * 4 - 2, 5);
        f2[i] -= f(i + 1, 2);
        f5[i] -= f(i + 1, 5);
    }
    for(int i = 1; i <= n; i ++)
    {
        f2[i] += f2[i - 1];
        f5[i] += f5[i - 1];
    }
//     cout << f2[n] << ' ' << f5[n] << ' ';
    cout << f5[n] << "\n";
    return 0;
}

L. 最长连续相同字符(字符线段树)

输入

10 3
aabbbccdde
1 1 5
2 3 a
1 1 5

输出

3 5
1 3

点击查看代码
#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

struct oper
{
	int l, r, len;
	char ch;
};

struct node
{
	int l, r;
	oper maxl, maxr, maxn;
}tr[N << 2];

int n, m;
string s;

oper max(oper &a, oper &b)
{
	if(a.len == b.len) return a.l < b.l ? a : b;
	return a.len > b.len ? a : b;
}

void pushup(node &u, node &l, node &r)
{
	u.maxl = l.maxl;
	if(l.maxl.r == l.r&&l.maxl.ch == r.maxl.ch)
		u.maxl = {l.maxl.l, r.maxl.r, r.maxl.r - l.maxl.l + 1, l.maxl.ch};
	u.maxr = r.maxr;
	if(r.maxr.l == r.l&&r.maxr.ch == l.maxr.ch)
		u.maxr = {l.maxr.l, r.maxr.r, r.maxr.r - l.maxr.l + 1, r.maxr.ch};
	u.maxn = max(l.maxn, r.maxn);
	if(l.maxr.ch == r.maxl.ch)
	{
		oper t = {l.maxr.l, r.maxl.r, r.maxl.r - l.maxr.l + 1, l.maxr.ch};
		u.maxn= max(u.maxn, t);
	}
}

void pushup(int u)
{
	pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r)
{
	if(l == r)
		tr[u] = {l, r, {l, r, 1, s[l]}, {l, r, 1, s[l]}, {l, r, 1, s[l]}};
	else
	{
		tr[u] = {l, r};
		int mid = l + r >> 1;
		build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
		pushup(u);
	}
}

void modify(int u, int x, char ch)
{
	if(tr[u].l == x&&tr[u].r == x)
		tr[u] = {x, x, {x, x, 1, ch}, {x, x, 1, ch}, {x, x, 1, ch}};
	else
	{
		int mid = tr[u].l + tr[u].r >> 1;
		if(x <= mid) modify(u << 1, x, ch);
		else modify(u << 1 | 1, x, ch);
		
		pushup(u);
	}
}

node query(int u, int l, int r)
{
	if(tr[u].l >= l&&tr[u].r <= r) return tr[u];
	
	int mid = tr[u].l + tr[u].r >> 1;
	if(r <= mid) return query(u << 1, l, r);
	if(l > mid) return query(u << 1 | 1, l, r);
	
	node ans, le = query(u << 1, l, r), ri = query(u << 1 | 1, l, r);
	pushup(ans, le, ri);
//	pushup(ans, query(u << 1, l, r), query(u << 1 | 1, l, r));
//	pushup(ans, query(u << 1, l, r), query(u << 1 | 1, l, r));
	return ans;
}

void solve()
{
	cin >> n >> m >> s;
	s = " " + s;
	build(1, 1, n);
	while(m --)
	{
		int op;
		cin >> op;
		if(op == 1)
		{
			int l, r;
			cin >> l >> r;
			node ans = query(1, l, r);
			cout << ans.maxn.l << ' ' << ans.maxn.r << endl;
		}
		else
		{
			int x;
			char ch;
			cin >> x >> ch;
			modify(1, x, ch);
		}
	}
}

int main()
{
	int T = 1;
	while(T --)
		solve();
	return T ^ T;
	
}