[LGR-123] 洛谷10月月赛 Div.2 T1~3 解析及代码

[LGR-123] 洛谷10月月赛 Div.2 T1~3 解析及代码

T1 暴龙的白菜

题目大意:

给定一个字符串,由 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3…以此类推,依次拼接而成。

现在有 T T T组询问,每次询问字符串中第 l l l位到第 r r r位上的数字之和,求这些询问的结果。

对于所有数据, 1 ≤ T ≤ 1 0 5 1 \le T \le 10^5 1T105 1 ≤ l ≤ r ≤ 1 0 6 1 \le l \le r \le 10^6 1lr106

思路:

考虑到 l l l r r r最大只有 1 0 6 10^6 106,所以我们显然可以把这个字符串构造出来再维护其前缀和。

时间复杂度 O ( n ) O(n) O(n)

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>

using namespace std;

typedef long long LL;

const int N = 1e6 + 5000;

int l, r, a[N];
LL ans = 0, s[N];

void init() //构造字符串
{
	int j = 1, k;
	for(int i = 1 ; i <= 9 ; i ++ )
		for(k = 1 ; k <= i ; j ++ , k ++ )
			a[j] = i;
	j ++ ;
	for(int i = 10 ; i <= 99 ; i ++ )
		for(k = 1 ; k <= i ; j += 2, k ++ )
			a[j - 1] = i / 10, a[j] = i % 10;
	j ++ ;
	for(int i = 100 ; i <= 819 ; i ++ )
		for(k = 1 ; k <= i ; j += 3, k ++ )
			a[j - 2] = i / 100, a[j - 1] = (i - 100 * a[j - 2]) / 10, a[j] = i % 10;
	
	for(int i = 1 ; i <= 1002375 ; i ++ )
		s[i] = s[i - 1] + a[i];
}

int main()
{
	int T;
	scanf("%d", &T);
	init();
	while(T -- )
	{
		ans = 0;
		scanf("%d%d", &l, &r);
		
		printf("%lld\n", s[r] - s[l - 1]);
	}
	
	return 0;
}

T2 So What Do We Do Now?

题目大意:

给定一棵由 n n n个节点构成的树,记 R i R_i Ri为以节点 i i i为根节点的子树中点权的极差,现在要求你构造一组点权,使得:

  1. 所有点的点权各不相同;
  2. 所有点的点权均为整数且在 [ 1 , n ] [1,n] [1,n]中;
  3. ∑ i = 1 n R i \sum_{i=1}^{n}R_i i=1nRi最小。

对于所有数据, 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1n106

思路:

显然,由于每个节点的权值各不相同且在 [ 1 , n ] [1,n] [1,n]的范围内,所以在一棵以 i i i节点为根,大小为 s i z e i size_i

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值