其他分享
首页 > 其他分享> > XIX Open Cup Onsite: E - Power of Function (数位+思维)

XIX Open Cup Onsite: E - Power of Function (数位+思维)

作者:互联网

观察到:我们可以从高位到第低位枚举第一个l和r不同的位置,记为diff,那么使得m取得最大的n有两种情况:要么n=r,要么n!=r,如果n!=r,那么要使得m最大,只有在

\[diff<=x<最大的位数 \]

时,在[0,x-1]位上,n与r相同,x位上n=mr[x]-1,[x+1,最大位数]上全部填上k-1,故可以枚举x,加一个前缀和优化,复杂度是O(Tlogkr)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;
int T, k, l, r;
int l_k[110], r_k[110], sumr_k[110];//l_k是l的k进制表示,从最高位向最低位排序,r_k是r的k进制表示,sumr_k是r_k的前缀和
int kplus[110];
int kbit, ma;
vector<int> max_num, min_num;

signed main()
{
	scanf("%lld", &T);
	int cnt = 0;
	while (T--) {
		scanf("%lld%lld%lld", &k, &l, &r);
		kbit = 0;
		//将l,r分解成k进制
		int t = r;
		while (t)t /= k, kbit++;
		kplus[0] = 1;
		for (int i = 1; i <= kbit; i++)kplus[i] = kplus[i - 1] * k;
		for (int i = 0, j = kbit - 1; i < kbit; i++, j--) {
			l_k[i] = l / kplus[j] % k, r_k[i] = r / kplus[j] % k;
			//前缀和
			if (!i)sumr_k[i] = r_k[0];
			else sumr_k[i] = sumr_k[i - 1] + r_k[i];
		}

		max_num.clear();
		min_num.clear();
		//找出第一个不同的位置
		int diff = 0;
		for (; diff < kbit; diff++)
			if (l_k[diff] != r_k[diff])break;

		//特判第一位填0
		bool zero = 0;
		if (!diff&&r_k[0] == 1)zero = 1;

		ma = 0;
		int min_id = kbit, maid = -1;
		//枚举x
		for (int i = diff; i < kbit; i++) {
			if (!r_k[i])continue;
			int tot = kbit;
			if (zero && !i)tot--;
			if (i)tot += sumr_k[i - 1];
			tot += r_k[i] - 1;
			tot += (kbit - i - 1)*(k - 1);
			if (tot > ma) {
				ma = tot;
				maid = min_id = i;
			}
			else if (tot == ma) {
				maid = max(maid, i);
				min_id = min(min_id, i);
			}
		}
		//两种情况取最大
		vector<int>ans1, ans2;
		int ma2 = 0;
		for (int i = 0; i < kbit; i++)ma2 += r_k[i];
		ma2 += kbit;
		if (ma2 > ma) {
			for (int i = 0; i < kbit; i++)max_num.push_back(r_k[i]), min_num.push_back(r_k[i]);
		}
		else if (ma2 == ma) {
			for (int i = 0; i < kbit; i++)min_num.push_back(r_k[i]);
			for (int i = 0; i < min_id; i++)max_num.push_back(r_k[i]);
			max_num.push_back(r_k[min_id] - 1);
			for (int i = min_id + 1; i < kbit; i++)max_num.push_back(k - 1);
		}
		else {
			for (int i = 0; i < min_id; i++)max_num.push_back(r_k[i]);
			max_num.push_back(r_k[min_id] - 1);
			for (int i = min_id + 1; i < kbit; i++)max_num.push_back(k - 1);

			for (int i = 0; i < maid; i++)min_num.push_back(r_k[i]);
			min_num.push_back(r_k[maid] - 1);
			for (int i = maid + 1; i < kbit; i++)min_num.push_back(k - 1);
		}
		//输出
		int xiao = 0, da = 0;
		for (int i = 0, j = kbit - 1; i < kbit; i++, j--)xiao += max_num[i] * kplus[j];
		for (int i = 0, j = kbit - 1; i < kbit; i++, j--)da += min_num[i] * kplus[j];

		printf("Case #%lld: %lld %lld %lld\n", ++cnt, max(ma, ma2) - 2, xiao, da);

	}
}

标签:Onsite,Function,Power,min,int,back,kbit,++,num
来源: https://www.cnblogs.com/codjjj/p/16171938.html