首页 > 其他分享 >【题解】P3583 [POI2015] KWA

【题解】P3583 [POI2015] KWA

时间:2022-10-05 12:55:05浏览次数:79  
标签:KWA return 题解 31 P3583 res inline ll

模拟赛出这道题???

还好赛时乱搞做出来了(/hanx

link

Description

定义一个数 \(n\) 的拆分为:将 \(n\) 表示为若干个不同的正整数的平方和。令 \(k(n)\) 为 \(n\) 的拆分中最大数的最小值。若不存在满足要求的拆分,则 \(k(n)=\infty\)。

给定 \(n\)(\(n\le10^{18}\)),求 \(k(n)\) 以及 \(\sum_{i=1}^n[\exists j>i,k(j)<k(i)]\)。

Solution

赛时看到 1e18 直接震惊

这个拆分似乎没有什么好性质,于是暴力算一下 \(1\sim10^4\) 以内的数,发现只有 \(2\sim128\) 中的 \(31\) 个数无法被表示。大胆猜测只有这几个数无法被表示。

令 \(S(n)=\sum_{i=1}^ni^2=\frac16n(n+1)(2n+1)\),\(t=\min\{x\mid S(x)\ge n\}\)。那么显然有 \(k(n)\ge t\)(否则全选也表示不了)。

上界不大好处理。正难则反,考虑从 \(S(t)\) 里蒯出几个不需要的平方数,即考虑 \(S(t)-n\)。由于 \(n\) 足够大,可以认定 \(n>S(t)-n\),于是我们缩小了要考虑的数的范围。如果 \(S(t)-n\) 能被表示出来,那么显然 \(k(n)=t\)。但是如果 \(k(S(t)-n)=\infty\) 就不能这样。

观察打表数据大胆猜测剩下这种情况是 \(k(n)= t+1\)。感性理解一下有 \(n-(t+1)^2\) 比较小,可以用 \(1\sim t\) 构造出来,于是 \(n\) 就构造出来了。\(S(t)-n\) 只有 \(31\) 种取值,所以 \(k(n)=t+1\) 也只有 \(31\) 个。

于是可以求出 \(k(n)\),时间复杂度感觉是比较松的 \(O(n^{1/3})\)?题解的 \(O(\log)\) 感觉不大对。

第二问考虑把 \(1\sim n\) 的数分为若干个 \((S(x-1),S(x)]\) 的块求解。\(t>30\) 后可以整块求解(每块只有 \(31\) 个取值为 \(x+1\) 的),前面的暴力就行了。

实际做的时候,\(n\) 比较小可能出问题,可以考虑预处理出一部分答案。我一开始预处理写错了结果你谷和模拟赛数据都没卡掉

时间复杂度就是求 \(k(n)\) 的复杂度。

code:

#include <cstdio>
#include <cmath>

typedef long long ll;
const ll Bad[31] = {2,3,6,7,8,11,12,15,18,19,22,23,24,27,28,31,32,33,43,44,47,48,60,67,72,76,92,96,108,112,128};
	// Numbers that can't be represented
const ll inf = 1e18;
const ll N = 9455,maxn = 2.5e4; // S(31) = 9455

ll n,t,k[maxn];

inline ll S(ll n) { return n * (n + 1) / 2 * (2 * n + 1) / 3; } // Prefix Square Sum

inline ll Get(ll n) { // Least t s.t. S(t) >= n
	ll t = pow(n * 3.,1. / 3);
	for(;S(t) >= n;) t --;
	for(;S(t) < n;) t ++;
	return t;
}

inline ll K(ll n) { // k(n)
	if(n <= N) return k[n];
	ll t = Get(n);
	if(K(S(t) - n) >= t) return t + 1;
	return t;
}

inline void Init() { // Pre-compute the value of k(i) for i in 1 ~ S(31)
	for(ll i = 1;i <= N;i ++) k[i] = inf;
	for(ll s = 0,i = 1;i <= 32;i ++,s += i * i)
		for(ll j = s;j >= 0;j --) if(k[j] < inf && k[j + i * i] > i) k[j + i * i] = i;
}

int main() {
	scanf("%lld",&n); Init();
	ll Cnt_res = 0,t,K_res = K(n);
	if(K_res < inf) printf("%lld",K_res); else putchar('-'); // Part 1
	for(ll i = 1;i <= N && i <= n;i ++) if(k[i] == inf || S(k[i] - 1) > i) Cnt_res ++; // 1 ~ S(31)
	if(n > N) {
		t = Get(n); Cnt_res += 31LL * (t - 31);
		for(int i = 0;i < 31;i ++) if(S(t) - Bad[i] <= n) Cnt_res ++;
	}
	printf(" %lld\n",Cnt_res); // Part 2
	return 0;
}

标签:KWA,return,题解,31,P3583,res,inline,ll
From: https://www.cnblogs.com/resorie/p/soln-p3583.html

相关文章

  • CF 547D. Mike and Fish 题解
    Solution1二分图染色显然这题是构造染色方案,于是我们考虑将矩阵转化成图进行染色。结论:将同一行的点两两配对,将同一列的点两两配对,形成的一定是二分图。证明:由于每......
  • P4572 题解
    前言题目传送门!更好的阅读体验?双倍经验:P3554(数据坑一点)。简要题意可以看P3554。思路:二分答案+树形DP。思路答案显然具有单调性,所以考虑二分答案。\(\operatorna......
  • P3226 [HNOI2012]集合选数 题解
    纪念一下30紫and500AC首先先膜拜一下神仙出题人,这题太神仙了。题意:要构造一个集合,使得$x\inA$,满足$2x\notinA$且$3x\notinA$,求\(\{1,2,\ldots,n\}\)......
  • 【Ynoi2009】 rla1rmdq 题解 (离线分块 + 线性空复处理)
    洛谷传送门分块。Solution看到是区修区查,还有时限,不难想到是分块,根号复杂度。然后看到空间复杂度,需要离线下来转为线性复杂度。考虑如何分块。观察操作性质,发现节点......
  • 「CF1455G」Forbidden Value 题解 (DP,线段树合并)
    题目简介已知初始值\(x=0\),给定下面\(2\)种命令:set\(y\)\(v\),令\(x=y\),或花费\(v\)元钱删除该命令;if\(y\)...end,如果\(x==y\),执行if...end中的命令,否则跳......
  • [题解]洛谷 P4930、BZOJ 4221
    洛谷P4930考虑\(\varphi\)有什么性质,设\(x\)的质因数分解为\(\prod_{i=1}^mp_i^{a_i}\),那么\(n=\varphi(x)=\prod_{i=1}^m(p_i-1)\times\prod_{i=1}^mp_i^{a_i-1......
  • 「ROIR 2021 Day 1」题解
    loj有原题。别问为什么没T4,问就是不会,等以后来补。T1-两台机器设两台机子分别为\(a,b\),分\(4\)种情况:只用\(a\),只用\(b\),先\(a\)后\(b\),先\(b\)后\(a\),判断......
  • Windows下CLion中文乱码问题解决
    (目录)原因分析Windows内部采用UTF-16编码,对于中文操作系统使用GBK编码,但是CLion默认文本编码为UTF-8,当编码不一致时,就会造成输出乱码,甚至编译不通过。解决方案当然,对于......
  • 类与对象课件问题解答
    结果:true 结果:false原因:当“==”施加于原始数据类型变量时,是比较变量所保存的数据是否相等。     当“==”施加于引用类型变量时,是比较这两个变量是否引用......
  • Luogu P5089 [eJOI2018] 元素周期表 题解
    (从洛谷博客搬过来的)这道题嘛..主要还是找性质推规律。拿到题,第一眼:噢噢爆搜啊。第二眼:噢噢贪心啊。第三眼:很好贪心假了。然后苦思冥想半个小时去看题解。看到兔队的......