2024.9.23校测

T1

题目描述

如果你有一个长度为 n 的序列:a1,a2,a3,,an,那么它的一个逆序对是一个二元组:<i,j> 满足 i<jai>aj,其中 i,j[1,n]

我们称一个序列所包含的逆序对的个数为这个序列的逆序对数。

那么问题来了:

我给出一个长度为 n 的序列,需要你计算:

a1,a2,,an1,ana2,a3,,an,a1a3,a4,,a1,a2an,a1,,an2,an1

n 个序列的逆序对个数之和。

输入格式

输入文件包含 2 行:

11 个整数:n,表示给定序列的长度。

2n 个整数:a1,a2,,an,表示初始序列。

输出格式

输出 n 个序列的逆序对个数的和。

输入样例1

3
2 2 3

输出样例1

3

样例1解释

以上样例中,3 个序列分别是:2,2,32,3,23,2,2,分别有 0,1,2 个逆序对,所以和为 3

输入样例2

3
1 1 1

输出样例2

0

样例2解释

以上样例中,3 个序列都是:1,1,1,逆序对数为 0,所以答案为 0

数据规模

对于 30% 数据,1n300

对于 60% 数据,1n5000

对于 100% 数据,1n106,1ain

完整代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 9;
int t[N * 24], a[N << 1], n, now, ans;
int lowbit(int x){
	return x & (-x);
}
void insert(int p, int x){
	for(int i = p; i <= n; i += lowbit(i))
		t[i] += x;
}
int query(int p){
	int ret = 0;
	for(int i = p; i; i -= lowbit(i))
		ret += t[i];
	return ret;
}
signed main(){
	freopen("rotinv.in", "r", stdin);
	freopen("rotinv.out", "w", stdout);
	scanf("%lld", &n);
	for(int i = 1; i <= n; i++){
		scanf("%lld", &a[i]);
		a[n + i] = a[i];
	}
	for(int i = 1; i <= n; i++){
		now += (i - 1) - query(a[i]);
		insert(a[i], 1);
	}
	ans = now;
	for(int i = n + 1; i < n + n; i++){
		insert(a[i - n], -1);
		now += (n - 1) - query(a[i]);
		now -= query(a[i - n] - 1);
		insert(a[i], 1);
		ans += now;
	}
	printf("%lld", ans);
	return 0;
} 

T2

题目描述

你有一堆柱子,它们竖直地并排摆放在桌子上,它们的高度分别是:h1,h2,h3,,hn

你从前往后看,能够看见的柱子个数为这个柱子序列的“可见度”(能够看见柱子 i 当且仅当 hj<hij<i)。

现在给你一个长度为 n 的序列,还有 m 个询问,每次询问某个区间 [l,r] 的柱子单独拿出来后,其可见度是多大。

输入格式

12 个整数:n,m,表示给出的柱子序列的长度和询问数。

2n 个整数:a1,a2,a3,,an,表示每根柱子对应的高度。

接下来 m 行,每行 2 个整数:l,r,表示对区间 [l,r] 进行询问。

输出格式

对于每个询问,输出答案。

输入样例

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

输出样例

3
2
2
1

样例解释

样例中“能够看见”的柱子的高度分别是:1,3,43,41,33

数据规模

对于 30% 的数据,1n,m103

对于 100% 的数据,1n,m105,1ain,1lrn

T3

题目描述

给你一棵无根树,边有边权,且是 [0,9] 之间的整数,给你 m 个询问,每次询问两个点 u,v 之间的路径的边的边权顺次连接起来后构成的那个数字取模于 31

输入格式

12 个整数:n,m,表示树的节点个数和询问数。

接下来 n1 行,每行 3 个数:u,v,d 表示点 u 和点 v 之间有一条边权为 d 的边。

接下来 m 行,每行 2 个整数:u,v 表示一个询问。

输出格式

对于每个询问输出其答案。

输入样例

5 3
1 2 2
1 3 8
3 4 9
3 5 2
1 4
2 5
5 2

输出样例

27
24
6

样例解释

样例中三条路径对应的数字分别是:89,582,285,它们被 31 取模后为:27,24,6

数据规模

对于 30% 的数据,1n,m103

对于 100% 的数据,1n,m105,1u,vn,uv,0d9

仍需调试的代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9, MOD = 31;
struct Edge{
	int v, w, nex;
} e[N << 1];
int head[N], ecnt;
void addEdge(int u, int v, int w){
	e[++ecnt] = Edge{v, w, head[u]};
	head[u] = ecnt;
}
int fa[N][20], siz[N], dep[N], num1[N], num2[N];
void dfs(int u, int f){
	dep[u] = dep[f] + 1;
	fa[u][0] = f;
	for(int i = 1; (1 << i) <= dep[u]; i++)
		fa[u][i] = fa[fa[u][i - 1]][i - 1];
	for(int i = head[u]; i; i = e[i].nex){
		int v = e[i].v, w = e[i].w;
		if(v == f)
			continue;
		if(u == 1)
			num1[v] = num2[v] = e[i].w;
		else {
			if(num1[u] / 10 == 0)
				num1[v] = (w * 10 + num1[u]) % MOD;
			else
				num1[v] = (w * 100 + num1[u]) % MOD;
			num2[v] = (num2[u] * 10 + w) % MOD;
		}
		dfs(v, u);
	}
}
int lca(int x, int y){
	if(dep[x] < dep[y])
		swap(x, y);
	for(int i = 19; i >= 0; i--)
		if(dep[x] - (1 << i) >= dep[y])
			x = fa[x][i];
	if(x == y)
		return x;
	for(int i = 19; i >= 0; i--)
		if(fa[x][i] != fa[y][i]){
			x = fa[x][i];
			y = fa[y][i];
		}
	return fa[x][0];
}
int n, m;
int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i < n; i++){
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		addEdge(u, v, w);
		addEdge(v, u, w);
	}
	dfs(1, 0);
	for(int i = 1; i <= m; i++){
		int u, v;
		scanf("%d%d", &u, &v);
		int l = lca(u, v);
		int tmp1 = num1[l], tmp2 = num1[u];
		while(tmp1 > 0){
			tmp1 /= 10;
			tmp2 /= 10;
		}
		int tmp3 = num2[l], tmp4 = num2[v], now = num2[v] % 10;
		while(tmp3 > 0){
			tmp3 /= 10;
			tmp4 /= 10;
			now = now * 10 + tmp4 % 10;
		}
		if(now / 10 == 0)
			printf("%d\n", (tmp2 * 10 + now) % MOD);
		else
			printf("%d\n", (tmp2 * 100 + now) % MOD);
	}
	return 0;
} 
posted @   JPGOJCZX  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示