拼好丸(二分) 题目描述panda来到kkkw的丸太店买丸太。他想要长度从 1 到 n 的 n 种不同长度的丸太各 1 根。丸太店里有长度从 1 到 n1 的 n1 种不同长度的丸太每根售价 1 日元。每种长度的丸太库存都只有 1 根。panda可以随意进行切割操作。也就是说如果 LL1​⋯Lk​那么他可以把一根长度为 L 的丸太切割成长度分别为 L1​,…,Lk​ 的 k 根丸太这个操作可以进行任意多次。此外他可以随意丢弃不需要的丸太。panda想要以尽可能低的价格获得所需的丸太。请你求出为了获得长度从 1 到 n 的 n 种不同长度的丸太各 1 根所需支付的最小金额。输入格式输入通过标准输入给出格式如下n输出格式输出获得长度从 1 到 n 的 n 种不同长度的丸太各 1 根所需支付的最小金额。输入输出样例 #1输入 #14输出 #13输入输出样例 #2输入 #2109109109109109109输出 #2109109108641970782说明/提示样例解释 1例如可以按如下方式用 3 日元获得所有需要的丸太购买长度为 2,4,5 的丸太将长度为 5 的丸太切割成两根长度为 1 的丸太和一根长度为 3 的丸太丢弃一根长度为 1 的多余丸太大样例见选手目录下的rice/rice.in和rice/rice.out。限制1≤n≤1018#includebits/stdc.h using namespace std; long long n,ans,yu; int main(){ scanf(%lld,n); ansn1; long long l1,r5e9; while(lr){ long long mid(lr)/2; long long s(1mid)*mid/2; if(sans){ yumid; lmid1; } else rmid-1; } printf(%lld,ans-yu); return 0; }总结1.题意输入4输出3我们就拿这一个样例来解释吧~~~panda要的丸太长度分别是1234。而丸太店刚刚好有长度从1到n1的n1种不同长度的丸太12345。要使panda要花日元越少那必须用n15的闲丸太来割成所需丸太如果不用的话这道题就没意思了panda可以随意进行切割操作注意一般切成越小的越好从小到大。紧绷我们开始从1的长度来砍5-14还可以继续砍又砍长度为2的丸太4-22还有剩按此操作2-3-1超了把长度2的丸太丢掉。如下表操作1操作2应切长度12剩余长度42还有例外可以按样例解释来~~~如下表操作1操作2应切长度13剩余长度412.用什么方法绷不住了n既然为10的18次方就算一个for循环o(n)也是10的18次方超麻了~~~就是这样我们要知道用什么方法咱们必须提前清楚神秘算式起始数结尾数*项数/2连续数列公式其中我们干肯定的是起始数他必定为1是因为最小丸太的长度为1既然起始数为1项数就等于结尾数要找的数就锁定了。说实话for循环都不行于是我想到了二分while是个绝佳的办法于是咱们就痛快地定好了用二分查找可以不买的最多个数最后用丸太店里丸太的个数-可以不买丸太的最多个数......3.代码怎么写首先变量肯定必不可少。long long n,ans,yu;//ans为答案做铺垫yu为二分做准备。//注意审题要开long long龙龙scanf(%lld,n);ansn1;//丸太店里丸太的个数然后就可以二分了long long l1,r5e9;//在1至n中有那几个丸太可以不买while(lr){long long mid(lr)/2;//取区间中间值__int128 s(1mid)*mid/2;//存储神秘公式if(sans){//判断是否能从为长度为n1的丸太中✂出1至mid长度的丸太yumid;//记录可以的丸太个数lmid1;//可以✂出丸太尝试✂出更多丸太}else rmid-1;//‍不能✂出丸太尝试少✂出一些丸太}最后输出printf(%lld,ans-yu);//用丸太店里丸太的个数-可无需买的丸太数量4.神秘额外疑问不会受着对了肯定有人想问__int128是干什么的我们为了保证数据范围于是要可以用到__int128不用也可以AC。其实我也不会于是我查了一下,....................(绷不住了)链接https://oi-wiki.org/lang/var/️ ️ ️ ️ ️ ❤️终是写完