2022牛客寒假算法基础集训营2(12/13)

A

小沙的炉石

结论题,手玩一下可以知道,假设攻击a次,恢复b次,且a<=b+1,那么攻击、恢复、攻击、恢复...这样组成的等差数列为区间左端点,求和得出a^{2},恢复、恢复、恢复...攻击、攻击、攻击...这样可以构成区间右端点,求和得出a*(b+1)+\frac{a*(a-1)}{2},那么区间什么时候可以合并?假设攻击次数为a-1,当且仅当(a-1)*(b+1)+\frac{(a-2)*(a-1)}{2}\geq a^{2}-1,而且a<=b+1,结合可以得出a>=4且b>=3时,组成连续的一段区间,现在只需要特判b==1和b==2的情况,手算一下可知b==1时3取不到,b==2时8取不到

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    LL n, m;
    int k;
    cin >> n >> m >> k;
    n = min(n, m + 1);
    LL minn = 1;
    LL maxx = n * (m + 1) + n * (n - 1) / 2;
    for (int i = 0; i < k; i++) {
        LL x;
        cin >> x;
        if (m == 1 and x == 3 or m == 2 and x == 8) {
            cout << "NO\n";
            continue;
        }
        if (x >= minn and x <= maxx) {
            cout << "YES\n";
        }
        else {
            cout << "NO\n";
        }
    }
    return 0;
}

B

小沙的魔法

B题1操作就是加边,让图连通块更大,2操作就是一个连通块里所有点权+1,那这样就可以有个贪心的思想,就是一个连通块需要加的次数就是所有数值中的最大值(这应该很容易理解),那么我们就可以考虑先将所有的值都加起来,一会操作的时候再减去小的,在输入边的时候我们应该存储小的点权,因为我们一开始已经把所有点的点权都加起来了,我们下一步操作就是减去连通块中点权较小的,然后再贪心一下,我们应优先去减去点权较小的中的较大者,然后就是开心的用并查集连通每一个点形成连通块了,因为会有什么重边和自环,而且操作只有min(5n,m),所以每次操作都是很珍贵的,所以只有有效的连边操作才是算到操作里的,至于可能用不着那么多次数,那重边和自环随便怎么弄都对结果没有影响

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
struct node {
    int u, v;
    LL height;
    bool operator <(const node &a) {
        return a.height < height;
    }
}e[5000010];
int a[500010], n, m, fa[500010];
LL sum;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum += a[i];
        fa[i] = i;
    }
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        e[i].u = u;
        e[i].v = v;
        e[i].height = min(a[u], a[v]);
    }
    sort(e, e + m);
    int cnt = min(5 * n, m);
    for (int i = 0; i < m; i++) {
        if (cnt == 0) {
            break;
        }
        function<int(int)> getfa = [&](int x) {
            return x == fa[x] ? x : fa[x] = getfa(fa[x]);
        };
        int a = getfa(e[i].u), b = getfa(e[i].v);
        if (a != b) {
            fa[a] = b;
            sum -= e[i].height;
            cnt--;
        }
    }
    cout << sum << '\n';
    return 0;
}

C

小沙的杀球

贪心,能杀就杀,不能杀就休息,签到题

AC代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <numeric>
#include <iomanip>
#define lowbit(x) ((x) & -(x))
using namespace std;
const int INF = 0x3f3f3f3f;

void solve() {
	long long x, a, b;
	cin >> x >> a >> b;
	string s;
	cin >> s;
	long long ans = 0;
	int len = s.length();
	for (int i = 0; i < len; i++) {
		if (s[i] == '0' || x < a) {
			x += b;
		}
		else {
			x -= a;
			ans++;
		}
	}
	cout << ans << endl;
	return;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int _t = 1;
	//cin >> _t;
	while (_t--) {
		solve();
	}
	return 0;
}
/*
1  2  

*/

D

小沙的涂色

大模拟,首先想出构造方法,找到构造规律,构造方法很多

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int n;
int a[1010][1010];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n;
    int idx = 0;
    function<void(int, int)> D1 = [&](int x, int y) {
        for (int i = x; i <= n; i += 3) {
            for (int j = y; j <= n; j += 2) {
                a[i][j] = a[i][j + 1] = a[i + 1][j] = ++idx;
                a[i + 1][j + 1] = a[i + 2][j] = a[i + 2][j + 1] = ++idx;
            }
        }
    };
    function<void(int)> D2 = [&](int x) {
        for (int i = x; i <= n; i++) {
            if (i & 1) {
                a[i - 1][1] = a[i][1] = a[i][2] = ++idx;
            } else {
                a[i - 1][3] = a[i][2] = a[i][3] = ++idx;
            }
        }
    };
    function<void(int, int)> D3 = [&](int x, int y) {
        for (int j = y; j <= n; j += 3) {
            a[x][j] = a[x][j + 1] = a[x + 1][j] = ++idx;
            a[x][j + 2] = a[x + 1][j + 2] = a[x + 1][j + 1] = ++idx;
        }
    };
    if (n == 1) {
        cout << "YES\n";
        cout << 0 << '\n';
    } else if (n % 3 == 0) {
        cout << "NO\n";
    } else if (n % 3 == 1) {
        idx = 5;
        a[1][1] = a[1][2] = a[2][1] = 1;
        a[4][3] = a[4][4] = a[3][4] = 2;
        a[3][1] = a[3][2] = a[4][2] = 3;
        a[2][2] = a[2][3] = a[3][3] = 4;
        a[1][3] = a[1][4] = a[2][4] = 5;
        D3(1, 5);
        D3(3, 5);
        if (n & 1) {
            D2(5);
            D1(5, 4);
        } else {
            D1(5, 1);
        }
        cout << "YES\n";
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cout << a[i][j] << " \n"[j == n];
            }
        }
    } else if (n % 3 == 2) {
        a[1][1] = a[1][2] = a[2][2] = ++idx;
        D3(1, 3);
        if (n & 1) {
            D2(3);
            D1(3, 4);
        } else {
            D1(3, 1);
        }
        cout << "YES\n";
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cout << a[i][j] << " \n"[j == n];
            }
        }
    }
    return 0;
}

E

小沙的长路

 大体意思就是说先考虑最小值,遍历1到n个点的路径的最小值,考虑不走环直接一个点一个点的走,可知n个点之间只有n-1条边,再考虑最大值就是尽可能的多走环,这时要考虑点的奇偶性,可知如果点的个数是奇数,那么对于完全图来说每个点的出入度之和一定为偶数,这样可以直接构造欧拉回路,而对于点的个数是偶数来说,每个点的出入度之和一定是奇数,那么我们只能留下两个点来作为起始点和终止点,倘若留下一个的话肯定不是最长的,这两个点的出入度之和为奇数,其他点的出入度之和构造成偶数,这样就需要对一些边进行更改方向之类的操作,最终用总边长减去删去的边长就是最长路径

AC代码:

/*
Tips:
   1.int? long long?
   2.don't submit wrong answer
   3.figure out logic first, then start writing please
   4.know about the range
   5.check if you have to input t or not
   6.modulo of negative numbers is not a%b, it is a%b + abs(b)
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x) & -(x))
#define endl '\n'
#define IOS1 ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define IOS2 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<char> vc;
typedef long long ll;
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T>
T power(T a, int b) {
	T res = 1;
	for (; b; b >>= 1, a = a * a) {
		if (b & 1) {
			res = res * a;
		}
	}
	return res;
}
template <typename T>
inline void read(T& x)
{
	x = 0; int f = 1; char ch = getchar();
	while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
	while (isdigit(ch)) { x = x * 10 + ch - '0', ch = getchar(); }
	x *= f;
}
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const double PI = acos(-1.0);
const double eps = 1e-6;
inline int sgn(double x) {
	return x < -eps ? -1 : x > eps;
}

void solve() {
	long long n, l, r;
	cin >> n;
	if (n & 1) {
		l = n - 1;
		r = (n * n - n) / 2;
	}
	else {
		l = n - 1;
		r = (n * n - n) / 2 - n / 2 + 1;
	}
	cout << l << " " << r << endl;
	return;
}
int main() {
	IOS1;
	//IOS2;
	int __t = 1;
	// cin >> __t;
	for (int _t = 1; _t <= __t; _t++) {
		solve();
	}
	return 0;
}
/*

*/

F

小沙的算数

AC代码:

/*
Tips:
   1.int? long long?
   2.don't submit wrong answer
   3.figure out logic first, then start writing please
   4.know about the range
   5.check if you have to input t or not
   6.modulo of negative numbers is not a%b, it is a%b + abs(b)
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x) & -(x))
#define endl '\n'
#define IOS1 ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define IOS2 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<char> vc;
typedef long long ll;
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T>
T power(T a, int b) {
	T res = 1;
	for (; b; b >>= 1, a = a * a) {
		if (b & 1) {
			res = res * a;
		}
	}
	return res;
}
template <typename T>
inline void read(T& x)
{
	x = 0; int f = 1; char ch = getchar();
	while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
	while (isdigit(ch)) { x = x * 10 + ch - '0', ch = getchar(); }
	x *= f;
}
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const double PI = acos(-1.0);
const double eps = 1e-6;
inline int sgn(double x) {
	return x < -eps ? -1 : x > eps;
}
const int M = 1000000007;
long long a[1000010], f[1000010];
int it = 1;
long long res, id[1000010];
long long calc(long long a, long long b) {
	a += b;
	return (a >= M) ? a - M : a;
}
long long ksm(long long a, long long b) {
	long long ans = 1;
	for (; b; b >>= 1, a = a * a % M) {
		if (b & 1) {
			ans = ans * a % M;
		}
	}
	return ans % M;
}
void solve() {
	int n, t;
	string s;
	cin >> n >> t >> s;
	s = 'X' + s;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		f[i] = 1;
	}
	for (int i = 1; i <= n; i++) {
		f[it] = f[it] * a[i] % M;
		id[i] = it;
		if (s[i] == '+') {
			it++;
		}
	}
	for (int i = 1; i <= it; i++) {
		res = calc(res, f[i]);
	}
	while (t--) {
		int i, j;
		cin >> i >> j;
		res = calc(res, M - f[id[i]]);
		f[id[i]] = f[id[i]] * ksm(a[i], M - 2) % M;
		f[id[i]] = f[id[i]] * j % M;
		a[i] = j;
		res = calc(res, f[id[i]]);
		cout << res << endl;
	}
	return;
}
int main() {
	IOS1;
	//IOS2;
	int __t = 1;
	// cin >> __t;
	for (int _t = 1; _t <= __t; _t++) {
		solve();
	}
	return 0;
}
/*

*/

G

小沙的身法

考虑LCA以及树上差分,先求一下每条由上到下以及由下到上的路径点权和,那么总的体力就是起点的高度+从u到lca(u,v)的消耗的和+从v到lca(u,v)的消耗的和,注意就是从低跳到高消耗体力,而从高跳到低不消耗体力,所以如果两点的差为负数应置为0,注意不要都开long long,否则MLE等着你

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int n, m;
int a[1000010], f[1000010][21], dep[1000010];
LL sum1[1000010], sum2[1000010];
vector<LL> G[1000010];
void dfs(int u, int fa) {
    dep[u] = dep[fa] + 1;
    f[u][0] = fa;
    sum1[u] = sum1[fa] + max(0ll, a[fa] - a[u]);
    sum2[u] = sum2[fa] + max(0ll, a[u] - a[fa]);
    for (int i = 1; (1 << i) < dep[u]; i++) {
        f[u][i] = f[f[u][i - 1]][i - 1];
    }
    for (auto v : G[u]) {
        if (v != fa) {
            dfs(v, u);
        }
    }
}
int lca(int x, int y) {
    if (dep[x] > dep[y]) {
        swap(x, y);
    }
    for (int i = 20; i >= 0; i--) {
        if (dep[x] <= dep[y] - (1 << i)) {
            y = f[y][i];
        }
    }
    if (x == y) {
        return x;
    }
    for (int i = 20 ; i >= 0; i--) {
        if (f[x][i] == f[y][i]) {
            continue;
        }
        x = f[x][i];
        y = f[y][i];
    }
    return f[x][0];
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1, 0);
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        cout << a[u] + sum1[u] + sum2[v] - sum1[lca(u, v)] - sum2[lca(u, v)] << '\n';
    }
    return 0;
}

H

小沙的数数

AC代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <numeric>
#include <iomanip>
#define lowbit(x) ((x) & -(x))
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;

void solve() {
	long long n, m;
	cin >> n >> m;
	if (m == 0) {
		cout << 1 << endl;
	}
	else {
		cout << n % mod << endl;
	}
	return;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int _t = 1;
	//cin >> _t;
	while (_t--) {
		solve();
	}
	return 0;
}
/*
cn 2;
n * n - 1 / 2
*/

I

小沙的构造

小模拟,考验代码基本功

AC代码:

/*
Tips:
   1.int? long long?
   2.don't submit wrong answer
   3.figure out logic first, then start writing please
   4.know about the range
   5.check if you have to input t or not
   6.modulo of negative numbers is not a%b, it is a%b + abs(b)
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x) & -(x))
#define endl '\n'
#define IOS1 ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define IOS2 ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef vector<int> vi;
typedef vector<long long> vll;
typedef vector<char> vc;
typedef long long ll;
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T>
T power(T a, int b) {
	T res = 1;
	for (; b; b >>= 1, a = a * a) {
		if (b & 1) {
			res = res * a;
		}
	}
	return res;
}
template <typename T>
inline void read(T& x)
{
	x = 0; int f = 1; char ch = getchar();
	while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
	while (isdigit(ch)) { x = x * 10 + ch - '0', ch = getchar(); }
	x *= f;
}
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const double PI = acos(-1.0);
const double eps = 1e-6;
inline int sgn(double x) {
	return x < -eps ? -1 : x > eps;
}
string s="X\"!'*+-.08:=^_WTYUIOAHXVM|<>\\/[]{}()";
char res[1005000];
void solve() {
	int n, m;
	cin >> n >> m;
	int l = 1, r = n;
	if (n < m || m > 35) {
		cout << -1 << endl;
		return;
	}
    if (m > 2 || (((l + 1) == r) && m == 2)) {
        res[l] = '(';
        res[r] = ')';
        l++;
        r--;
        m -= 2;
    }
    if (m > 2 || (((l + 1) == r) && m == 2)) {
        res[l] = '[';
        res[r] = ']';
        l++;
        r--;
        m -= 2;
    }
    if (m > 2 || (((l + 1) == r) && m == 2)) {
        res[l] = '{';
        res[r] = '}';
        l++;
        r--;
        m -= 2;
    }
    if (m > 2 || (((l + 1) == r) && m == 2)) {
        res[l] = '\\';
        res[r] = '/';
        l++;
        r--;
        m -= 2;
    }
    if (m > 2 || (((l + 1) == r) && m == 2)) {
        res[l] = '<';
        res[r] = '>';
        l++;
        r--;
        m -= 2;
    }
    while (l <= r) {
        if (m == 0) {
            res[l] = res[r] = '\"';
        }
        else {
            res[l] = res[r] = s[m];
            m--;
        }
        l++;
        r--;
    }
    if (m) {
        cout << -1;
        return;
    }
    cout << res + 1;
	return;
}
int main() {
	IOS1;
	//IOS2;
	int __t = 1;
	// cin >> __t;
	for (int _t = 1; _t <= __t; _t++) {
		solve();
	}
	return 0;
}
/*

*/

K

小沙的步伐

签到题,按题意模拟即可

AC代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast")
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <stack>
#include <numeric>
#include <iomanip>
#define lowbit(x) ((x) & -(x))
using namespace std;
const int INF = 0x3f3f3f3f;

void solve() {
	vector<int> a(11, 0);
	string s;
	cin >> s;
	int len = s.length();
	for (int i = 0; i < len; i++) {
		if (s[i] != '5') {
			a[s[i] - '0']++;
			a[5]++;
		}
	}
	for (int i = 1; i <= 9; i++) {
		cout << a[i] << " \n"[i == 9];
	}
	return;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int _t = 1;
	//cin >> _t;
	while (_t--) {
		solve();
	}
	return 0;
}
/*
1  2  

*/

L

小沙的remake(普通版)

L和M是一个题意只是数据范围不一样,所以直接在这里解释两个题,看到数据最大的那个题优先想到用数据结构去优化它,因此树状数组维护动态前缀和。先按照气运值排序,然后遍历一遍气运,每次求当前点和当前点前 b_i 位的区间和,并将该值加入到当前位下标的树状数组中进行更新。最后对 n 进行查询,结果即为要求的方案数

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

namespace GenHelper
{
    int z1,z2,z3,z4,z5,u,res;
    int get()
    {
        z5=((z1<<6)^z1)>>13;
        z1=((int)(z1&4294967)<<18)^z5;
        z5=((z2<<2)^z2)>>27;
        z2=((z2&4294968)<<2)^z5;
        z5=((z3<<13)^z3)>>21;
        z3=((z3&4294967)<<7)^z5;
        z5=((z4<<3)^z4)>>12;
        z4=((z4&4294967)<<13)^z5;
        return (z1^z2^z3^z4);
    }
    int read(int m) {
        u=get();
        u>>=1;
        if(m==0)res=u;
        else res=(u/2345+1000054321)%m;
        return res;
    }
     void srand(int x)
    {
        z1=x;
        z2=(~x)^(0x23333333);
        z3=x^(0x12345798);
        z4=(~x)+51;
          u = 0;
    }
}
using namespace GenHelper;
using namespace std;
const int N=2e6+7,mod=1e9+7;
int a[N],b[N];
struct node {
    int x, id;
    bool operator <(const node &a) {
        if (a.x != x) {
            return x < a.x;
        }
        return id < a.id;
    }
}s[N];
LL tree[N];
void add(int x, int y) {
    for (int i = y; i < N; i += i & (-i)) {
        tree[i] = (tree[i] + x) % mod;
    }
}
LL ask(int x) {
    LL res = 0;
    while (x) {
        res = (res + tree[x]) % mod;
        x -= x & (-x);
    }
    return res % mod;
}
int main(){
    int n,seed;
    scanf("%d %d",&n,&seed);
    srand(seed);
    for(int i=1;i<=n;i++){
        a[i]=read(0),b[i]=read(i);
        s[i].id = i;
        s[i].x = a[i];
    }
    sort(s + 1, s + 1 + n);
    for (int i = 1; i <= n; i++) {
        LL x = (ask(s[i].id - 1) - ask(s[i].id - 1 - b[s[i].id]) + 1 + mod) % mod;
        add(x, s[i].id);
    }
    cout << ask(n) << '\n';
    return 0;
}

M

小沙的remake(竞速版)

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;

namespace GenHelper
{
    int z1,z2,z3,z4,z5,u,res;
    int get()
    {
        z5=((z1<<6)^z1)>>13;
        z1=((int)(z1&4294967)<<18)^z5;
        z5=((z2<<2)^z2)>>27;
        z2=((z2&4294968)<<2)^z5;
        z5=((z3<<13)^z3)>>21;
        z3=((z3&4294967)<<7)^z5;
        z5=((z4<<3)^z4)>>12;
        z4=((z4&4294967)<<13)^z5;
        return (z1^z2^z3^z4);
    }
    int read(int m) {
        u=get();
        u>>=1;
        if(m==0)res=u;
        else res=(u/2345+1000054321)%m;
        return res;
    }
     void srand(int x)
    {
        z1=x;
        z2=(~x)^(0x23333333);
        z3=x^(0x12345798);
        z4=(~x)+51;
          u = 0;
    }
}
using namespace GenHelper;
using namespace std;
const int N=2e6+7,mod=1e9+7;
int a[N],b[N];
struct node {
    int x, id;
    bool operator <(const node &a) {
        if (a.x != x) {
            return x < a.x;
        }
        return id < a.id;
    }
}s[N];
LL tree[N];
void add(int x, int y) {
    for (int i = y; i < N; i += i & (-i)) {
        tree[i] = (tree[i] + x) % mod;
    }
}
LL ask(int x) {
    LL res = 0;
    while (x) {
        res = (res + tree[x]) % mod;
        x -= x & (-x);
    }
    return res % mod;
}
int main(){
    int n,seed;
    scanf("%d %d",&n,&seed);
    srand(seed);
    for(int i=1;i<=n;i++){
        a[i]=read(0),b[i]=read(i);
        s[i].id = i;
        s[i].x = a[i];
    }
    sort(s + 1, s + 1 + n);
    for (int i = 1; i <= n; i++) {
        LL x = (ask(s[i].id - 1) - ask(s[i].id - 1 - b[s[i].id]) + 1 + mod) % mod;
        add(x, s[i].id);
    }
    cout << ask(n) << '\n';
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值