[Comet OJ - Contest #4 D][39D 1584]求和_"数位dp"

求和

题目大意

数据范围



题解

脑筋急转弯可还行.....

我们发现只需要最后枚举个位/xk/xk

因为前面的贡献都是确定的了。

故此我们最后暴力统计一下就好咯。

不知道为啥我组合数一直过不去,暴力求过了呜呜。

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

ll rd() {
	ll x = 0;
	int f = 1;
	char c = nc();
	while (c < 48) {
		if (c == ‘-‘)
			f = -1;
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

int a[20], cnt, b[20];

ll C[20][20];

void init() {
	C[0][0] = 1;
	for (int i = 1; i <= 19; i ++ ) {
		C[i][0] = 1;
		for (int j = 1; j <= i; j ++ ) {
			C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % 10;
		}
	}
}

inline ll f(ll x) {
	cnt = 0;
	while (x) {
		a[ ++ cnt] = x % 10;
		x /= 10;
	}
	ll mdl = 0;
	for (int i = cnt; i >= 2; i -- ) {
		(mdl += C[cnt - 1][i - 1] * a[i] % 10) %= 10;
	}
	return mdl;
}

// inline ll f(ll x) {
// 	cnt = 0;
// 	for (; x; x /= 10)
// 		a[cnt ++ ] = x % 10;
// 	reverse(a, a + cnt);
// 	while(cnt != 1) {
// 		int m = 0;
// 		for (int i = 1; i < cnt; i ++ ) {
// 			int c = (a[i] + a[i-1]) % 10;
// 			if(!m && !c) continue;
// 			b[m ++ ] = c;
// 		}
// 		if (!m)
// 			b[m ++ ] = 0;
// 		cnt = m;
// 		for (int i = 0; i < cnt; i ++ )
// 			a[i] = b[i];
// 	}
// 	return a[0];
// }

ll calc(ll x) {
	if (x < 10ll) {
		return (x + 1) * x / 2;
	}
	ll ans = x / 10 * 45;
	ll mdl = f(x / 10 * 10);
	// cout << mdl << endl ;
	int tmp = x % 10;
	for (int i = 0; i <= tmp; i ++ ) {
		ans += (mdl + i) % 10;
	}
	return ans;
}

int main() {
	int T = rd();
	init();
	while (T -- ) {
		ll l = rd(), r = rd();
		printf("%llu\n", calc(r) - calc(l - 1));
	}
	return 0;
}

小结:真·脑筋急转弯.....

原文地址:https://www.cnblogs.com/ShuraK/p/11241235.html

时间: 2024-08-30 17:38:12

[Comet OJ - Contest #4 D][39D 1584]求和_"数位dp"的相关文章

Comet OJ - Contest #5

Comet OJ - Contest #5 总有一天,我会拿掉给\(dyj\)的小裙子的. A 显然 \(ans = min(cnt_1/3,cnt_4/2,cnt5)\) B 我们可以感性理解一下,最大的满足条件的\(x\)不会太大 因为当\(x\)越来越大时\(f(x)\)的增长速度比\(x\)的增长速度慢得多 其实可以证明,最大的满足的\(x\)不会超过\(100\) 因为没有任何一个三位数的各位之和大于等于\(50\) 所以我们就直接预处理\(1-99\)所有的合法的 暴力枚举即可 其实

符文能量(Comet OJ - Contest #8)

给Comet OJ打个小广告,挺好用的,比较简洁,给人感觉很好用 Contest #8是我打的第一场本oj比赛,很遗憾A了前两道傻逼题就没思路了,然后就不打算打了....... https://www.cometoj.com/contest/58/problem/C?problem_id=2760 怎么做啊完全不会啊我那么菜,虽然看到是dp但嫌太麻烦就放弃了: 靠后仔细想了想原来这道题很简单: 结构体node e[];储存ai,bi值(当然你用数组我也不拦着),因为合并的方式很特殊,可以不管合并

Comet OJ - Contest #10 B

Comet OJ - Contest #10 B 沉鱼落雁 思维题 题意 : 每个数字最多重复出现三次,有n给数字,让你尽可能的使得相同数字之间的最小距离尽可能大 思路 :分三种情况套路 设 a b c 分别代表出现 一次, 两次, 三次 数字的个数 所有元素至多出现一次,答案为 n,题目规定 所有元素至多出现两次, 例如 1 1 2,可以排列成 1 2 1,所以,答案为 1 例如 1 1 2 2 3,可以排列成 1 2 3 1 2,所有 答案为 2 思考后得出,应该尽可能的把 b 个出现两次的

Comet OJ - Contest #7 解题报告

传送门:https://www.cometoj.com/contest/52 A:签到题 题意:多次询问,每次询问给出一个值域区间[l,r],从这区间范围中选出两个整数(可重复),依次求出这俩数的“最大的最小公倍数”.“最小的最小公倍数”.“最大的最大公约数”.最小的最大公约数. 分析:(1)显然,当区间长度为1时,该问题的答案只能是区间中仅有的那个数. (2)当区间的长度大于1时,最大的最小公倍数,lcmmax =lcm(ar,ar-1) = ar * ar-1: 最小的最小公倍数,lcmmi

Comet OJ - Contest #15

https://cometoj.com/contest/79/problem/D?problem_id=4219 题目描述 ※ 简单版与困难版的唯一区别是粗体字部份和 $v$ 的数据范围. 在双 11 时,心慧精品店有个特别的折价活动如下: 首先,我们定义一个正整数为"好的"当且仅当此数仅由数字 1 构成,举例来说 1, 11, 111, 11111 都是「好的」,但 10.123.321 都是「不好的」. 接着,若一个商品原价为 x,若顾客能把 x 表示为 k 个「好的」数字,那么此

Comet OJ - Contest #15题解

A 双十一特惠 (简单版) n  <=  1e19,   1e9 > 1(8) https://www.cometoj.com/contest/79/problem/A?problem_id=4198 #include<bits/stdc++.h> using namespace std; int main(){ int t; cin >> t; while(t--) { int cnt1 = 0; int n;cin >> n; int pr[] = {1

Comet OJ - Contest #0

A:化成x-√n=y+z-√4yz的形式,则显然n是完全平方数时有无数组解,否则要求n=4yz,暴力枚举n的因数即可.注意判断根号下是否不小于0. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long

Comet OJ - Contest #1

A:随便怎么暴力. #include<bits/stdc++.h> using namespace std; #define ll long long #define N 25 char getc(){char c=getchar();while (c!='.'&&c!='#') c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char

Comet OJ Contest #2

A:暴力,显然每两次至少翻一倍. #include<bits/stdc++.h> using namespace std; #define ll long long #define inf 1000000010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} in