首页 > 其他分享 >「BZOJ2505」tickets 题解

「BZOJ2505」tickets 题解

时间:2023-10-17 17:45:48浏览次数:43  
标签:tickets return int 题解 tot BZOJ2505 step last include

preface

网上目前还没看到我的方法,就大概讲一下做法

solution

首先想到贪心,考虑 \([l, r]\) 的最大次数,一定是找到最小的 \(x\) 满足 \(l \sim x\) 的位数的和大于等于 \(k\),然后递归的求解 \([x + 1, r]\),易证。

还是考虑将 \(Query (l, r)\) 拆分成 \(Query (1, r)\) 和 \(Query (1, l - 1)\)

那么我们就有一个简单的数位 \(dp\),\(dfs (step, tot, last, limit)\) 表示从最高位考虑到 \(step\) 位,这些位的位数和位 \(tot\),上一个区间剩下 \(last\) 的位数和,是或否顶到上届,容易写出。

但是我们发现 \(Query (1, r) - Query (1, l - 1) \neq Query (l, r)\),问题在于 \([1, l - 1]\) 这个区间剩下的位数和给到 \([l, r]\) 可能会让答案多一。

怎么处理这个问题呢?考虑暴力就是如果当前考虑到了 \(l\),那么他就不从上一个区间继承 \(last\) 了,考虑记忆化搜索优化,那么只需要判断当前这个状态是否包含 \(l\),再加一维状态 \(past\) 用以判断当前这个区间是否包含 \(l\)。

code

//我看着,天真的我自己
#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdio> 
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define fi first
#define se second
#define MP(x,y) make_pair (x, y)
#define PII pair <int, int>
#define db double
#define LL long long
#define ULL unsigned long long
#define rep(i,j,k) for (int i = (j); i <= (k); i++)
#define per(i,j,k) for (int i = (j); i >= (k); i--)

template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }
template <typename T>
void read (T &x) {
	x = 0; bool fl_for_x = 1;
	char ch = getchar ();
	while (ch < '0' || ch > '9') {
		if (ch == '-') fl_for_x = 0;
		ch = getchar ();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 3) + (x << 1) + ch - '0';
		ch = getchar ();
	}
	if (!fl_for_x) x = -x;
}
template <typename T, typename... Args>
void read (T &x, Args&... args) {
	read (x), read (args...);
}
const int Maxn_For_Print = 30;
int Tp_For_Print, St_For_Print[Maxn_For_Print + 5];
template <typename T>
void write (T x) {
	if (x == 0) {
		putchar ('0');
		return;
	}
	if (x < 0) {
		x = -x;
		putchar ('-');
	}
	while (x) {
		St_For_Print[++Tp_For_Print] = x % 10;
		x /= 10;
	}
	while (Tp_For_Print) {
		putchar (St_For_Print[Tp_For_Print--] + '0');
	}
}
template <typename T>
void print (T x, char ch) {
	write (x), putchar (ch);
}

const int Maxn = 18;
const int Maxtot = 9 * 17;
const int Maxlast = 1e3;

LL l, r, k, w[Maxn + 5];
int tp, x[Maxn + 5];

pair <LL, int> dp[2][Maxn + 5][Maxtot + 5][Maxlast + 5];
bool vis[2][Maxn + 5][Maxtot + 5][Maxlast + 5];
LL calc (LL past, int step) {
	if (past <= l && l <= past + w[step] - 1) return 1;
	else return 0;
}
pair <LL, int> dfs (int step, int tot, int last, int Limit, LL past) {
	if (!Limit && vis[calc (past, step)][step][tot][last]) return dp[calc (past, step)][step][tot][last];

	if (step == 0) {
		if (past == l) {
			if (tot >= k) return MP (1, 0);
			else return MP (0, tot);
		}
		last += tot;
		if (last >= k) return MP (1, 0);
		else return MP (0, last);
	}
	int Up = Limit ? x[step] : 9;
	pair <LL, int> res = MP (0, last);
	rep (i, 0, Up) {
		pair <LL, int> tmp = dfs (step - 1, tot + i, res.se, Limit & (i == Up), past + (w[step - 1] * i));
		res = MP (res.fi + tmp.fi, tmp.se);
	}
	if (!Limit) dp[calc (past, step)][step][tot][last] = res, vis[calc (past, step)][step][tot][last] = 1;
	return res;
}
LL Query (LL qwq) {
	tp = 0;
	while (qwq) {
		x[++tp] = qwq % 10;
		qwq /= 10;
	}
	return dfs (tp, 0, 0, 1, 0).fi;
}

signed main () {
	// freopen ("C:\\Users\\Administrator\\Desktop\\lihan\\1.in", "r", stdin);
	// freopen ("C:\\Users\\Administrator\\Desktop\\lihan\\1.out", "w", stdout);
//	freopen ("transport.in", "r", stdin);
//	freopen ("transport.out", "w", stdout);

	w[0] = 1; rep (i, 1, Maxn) w[i] = w[i - 1] * 10;
	read (l, r, k);
	write (Query (r) - Query (l - 1));
	return 0;
}

标签:tickets,return,int,题解,tot,BZOJ2505,step,last,include
From: https://www.cnblogs.com/dsy-lh/p/17770256.html

相关文章

  • RTMP dimensions not set问题解决方案
    问题RTMP开始推流,打印错误提示:dimensionsnotset源码位置libavformat\mux.ccaseAVMEDIA_TYPE_VIDEO:if((par->width<=0||par->height<=0)&&!(of->flags&AVFMT_NODIMENSIONS)){av_log(s,A......
  • CF1879F Last Man Standing 题解
    原题翻译观察题目,容易发现当题目难度为\(x\)时一个OIer存活时间为\(h_i\lceil\frac{a_i}{x}\rceil\)发现\(a_i\)较小,所以我们先考虑暴力枚举\(x\in[1,\maxa_i]\),然后把原数组按\(a_i\)排个序,对于每组\(\lceil\frac{a_i}{x}\rceil\)相同的部分统一计算他......
  • visual studio智能提示出现慢的问题解决办法
    VisualStudio智能提示出现慢的问题解决办法如下:清理VisualStudio缓存。通过"文件"→"打开文件或项目"→"取消"→"是,清理所有项目"进行清理。清理VisualStudio实例。通过"文件"→"关闭解决方案"进行清理。重置用户数据。打开VisualStudio的开发人员命令提示符,输入devenv.ex......
  • CF1680F Lenient Vertex Cover 题解
    CF1680FLenientVertexCover题解这道题和「JOISC2014Day3」电压非常类似,或者说就是一道题。题意就是给你一个图,问能否对所有点黑白染色,允许最多一条边的两个顶点都染成黑色。黑白染色后其实就是一个二分图,那如果有一条边的两个顶点染成黑色,就是说去掉该边后,剩下的图为二分......
  • 题解:CF237D
    题目传送门思路构造\(k\)个集合,使这些集合满足以下性质:集合的并集为\(V\)。对于树\(s\)中的任意一条边\((a,b)\),都能在\(k\)个集合中找到一个集合\(x\)使得\(a,b\inx\)。对于树\(s\)中的任意一个点\(a\),所有在\(k\)个集合中包含了\(a\)的集合构成了......
  • 题解 P7468【[NOI Online 2021 提高组] 愤怒的小 N】
    题解P7468【[NOIOnline2021提高组]愤怒的小N】problem首先是有一个字符串\(S=\texttt{"0"}\),做无限次“将\(S\)的每一位取反接在\(S\)后面”的操作,形如\(S=0110100110010110\cdots\)。另外给一个\(k-1\)次多项式\(f\),求\(\sum_{i=0}^{n-1}S_if(i).\)\(n\leq......
  • 题解 ABC267F【Exactly K Steps】
    (accoders::NOI#5541.醉(intoxicated))题目描述Robin有一棵树,他有\(m\)次询问,每次询问他给你\(u,k\),你需要输出树上的一个节点\(v\)满足\(dist(u,v)=k\),或者报告无解。\(dist(u,v)\)表示树上\(u\)到\(v\)的最短路径的边数。\(n\leq10^5\)solution考虑求出每个......
  • Math teacher's homework 题解
    preface网上的题解看不懂,看代码看懂了:)solution考虑\(\mathrm{x_i}\)的倒数第\(\mathrm{low_i-1}\)位到倒数第\(\mathrm{1}\)位可以乱选(选\(\mathrm{0/1}\)都满足\(\mathrm{x_i\leqm_i}\)),那么就需要\(\mathrm{x_i}\)和\(\mathrm{m_i}\)的第\(\mathrm{1}\)位......
  • YACS 2023年9月月赛 甲组 题解
    题目链接1题目链接2题目链接3榜单终于公布了,这应该是第二长的榜单公布吧。(最长的一次是去年八月,拖到九月开始后才公布) T1是傻逼数据结构不说了吧,对于每个点枚举以他为角的$k\timesk$的四个正方形算一下点的数量,用$cdq$或者扫描线都行。看这个题目编号是$81$,看来是很......
  • 题解整理
    CF1740ACF1740BCF1740DCF1711BCF1253BCF1080BCF1237ACF1743ACF1743CCF1743BCF1370B......