AtCoder Beginner Contest 230

E

https://atcoder.jp/contests/abc230/tasks/abc230_e
先找出来 k 0 = f l o o r ( s q r t ( n ) ) k0 = floor(sqrt(n)) k0=floor(sqrt(n))
可以发现
f l o o r ( n / i ) = k floor(n / i) = k floor(n/i)=k
k < = n / i < = k + 1 k <= n / i <= k + 1 k<=n/i<=k+1
n / ( k + 1 ) < = i < = n / k n / (k + 1) <= i <= n / k n/(k+1)<=i<=n/k
这样我们可以在找出来公式

#include <bits/stdc++.h>
using namespace std ;
int main()
{
	long long n, sum, k ;
	cin >> n ;
	for (long long i = 1; i <= n; i ++ ) {
		if (i * i <= n) k = i ; 
		else break ;
	}
	sum = 0 ; 
	for (long long i = 1 ; i <= k; i ++ ) 
		sum += ((n / i) - (n / (i + 1))) * i ;
	for (long long i = 1 ;i <= n / (k + 1); i ++ ) sum += (n / i) ;
	cout << sum << endl ;
	return 0 ;
}

F

dp
递推
给出的是一个长度为N的序列A,你可以做任何次数的操作:当序列的长度至少为2时,选择两个相邻的值,删除它们,并在它们原来的位置插入它们的和。有多少个序列可以从零或更多的操作中产生?对答案取998244353的模数。

#include <bits/stdc++.h>
using namespace std ;
const int N = 2e5 + 10 ;
const int mod = 998244353 ;
int n ;
long long a[N] ;
long long f[N] ;
unordered_map<long long, long long>mp ;
int main()
{
	cin >> n >> a[1];
	//线性dp
	f[1] = 1 ;
	for (int i = 2; i <= n; i ++ ) {
		cin >> a[i] ;
		//f[i] = f[i - 1] * 2 - 重复部分 
		f[i] = ((f[i - 1] << 1) - mp[a[1]] + mod) % mod ;
		mp[a[1]] = f[i - 1] ;
		a[1] += a[i] ;
	}
	cout << f[n] << endl ;
	return 0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值