Olya and magical square - 竞赛题解

借鉴了一下神犇tly的博客QwQ(还是打一下广告

终于弄懂了

Codeforces 传送门


『题目』(直接上翻译了)

给一个边长为 \(2^n(n>0)\) 的正方形,你需要对它进行恰好 \(k(k>0)\) 次“剪切”,“剪切”的方法是:选取一个边长不为 \(1\) 的正方形,将它剪成 \(4\) 个大小相同的正方形,不能挪动位置。

要求在 \(k\) 次操作后存在一条路径:从左下角的正方形到右上角的正方形,且路径上所有正方形的大小都相等。

求是否可行,若存在可行解,输出可行解的路径上的正方形的边长以 \(2\) 为底的对数


『解析』

其实比较容易看出来是一道结论(找规律)题,毕竟也就只有这种类型之类的题会把 \(k\) 设置为 \(10^{18}\) 这么大……

大概的解题思路是:对于每一种可能的路径上正方形的边长 \(2^i\),求出这种情况最少需要进行多少次剪切以及最多需要多少次,判断 \(k\) 是否在这个区间内。

不妨让路径先一直向上,然后一直向右。假设现在路径上正方形的边长是 \(2^i\),

  1. 先求一下最少次数

    这种情况的最少操作次数为 \(1+3+7+...+(2^i-1)\),感性理解一下——

    当 \(i=n-1\) 时显然最少需要进行 \(1\) 次操作,这样就会变成:



    如果进一步让 \(i=n-2\),那么我们就应该对上图的灰色块进行操作,也就是 \(3\) 次。……以此类推,就会得到上面的式子~
  2. 然后求最大次数

    显然(一般来说)在最少次数的基础下我们还可以再进行一些不会对答案造成影响的操作——也就是对除了左下角到左上角再到右上角的路径上的正方形(最左边、最上边的正方形),我们最多可以把它们全部剪成\(1*1\)的~

    令 \(f(siz)\) 为将边长为 \(2^{siz}\) 的正方形剪成 \(1*1\) 的操作次数,那么我们发现 \(2^{siz}\) 的边长剪 \(1\) 次会变成 \(4\) 个 \(2^{siz-1}\),再剪 \(4\) 次会变成 \(16\) 个 \(2^{siz-2}\)……

    以此类推,我们可以得到 \(f(siz)=1+4+4^2+...+4^{siz-1}\) 。

    假设现在正方形的边长为 \(2^a\),左上角的正方形为 \(2^b(b<a)\),如果按照最小方法剪,那么正方形可能长这样:



    上面的蓝色部分就是我们可以乱剪(不会对答案造成影响)的正方形,假设我们已经算出来了这一块蓝色部分全部剪成 \(1*1\) 的操作次数,然后如果按照最小方法继续剪,它就会变成这样:



    上面的橙色部分就是相较上一次剪切多出来的可以任意操作而不会影响答案的正方形(假设它们的大小不是 \(1*1\)),那么我们要算这一次可以任意剪切的次数就可以根据上一次(蓝色部分)加上这次(橙色部分)全部剪成 \(1*1\) 的操作次数~

    而我们发现橙色正方形的边长就是我们的路径上的正方形边长,所以可以直接套用 \(f()\) 函数计算。至于个数……假设上一次多出来的正方形(蓝色里面除去右下角的正方形)的个数为 \(tmp'\) ,那么这次多出来的正方形个数就是 \(tmp=(tmp-1)*4+5\),找规律嘛~

    那么最大操作数就是最少操作数加上将这些(橙色和蓝色)正方形剪成 \(1*1\) 的正方形的操作数。

那么我们只要枚举一下答案的路径上的正方形边长,判断 \(k\) 是否在最小操作数和最大操作数之间即可。但是我们可以看到 \(n\) 也不小……所以这里还有一个 特性

当 \(n \geq 32\) 时,答案就是 \(n-1\)

为什么?显然如果我们要将边长为 \(2^m(m \geq 31)\) 的正方形全剪成 \(1*1\) 的正方形的总操作次数已经超过了 \(10^{18}\) ,这就意味着我们可以将原来 \(n \geq 32\) 的正方形剪成 \(4\) 个边长为 \(2^{n-1}\) 的正方形,然后就尽可能地将右下角的那一个边长为 \(2^{n-1}\) 的正方形剪成 \(1*1\) 的,但是 \(k\) 并不够大,所以就可以将剩下的 \(k-1\) 次机会全部用完~

代码比较简单,但是论证思路还是非常严谨的!


『源代码』

/*Lucky_Glass*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll QPow(ll a,int r){ //快速幂
ll res=1ll;
while(r){
if(r&1) res*=a;
a*=a;
r>>=1;
}
return res;
}
ll Cut(int siz){ //把边长为 2^siz 的正方形剪成 1*1 的操作次数
return (QPow(4,siz)-1)/3;
}
int Solve(int n,ll k){
if(n>=32) return n-1;
else{
ll liml=0,limu=0,sam=1;
//liml:最少操作次数
//limu:在最少操作次数的基础上最多还能进行的操作次数使得答案不变化
//sam:按最少操作方法与路径上的正方形大小相同的正方形(除去路径上的)的最大个数,也就是进行最少操作后相较上一次多出来的可以任意操作的正方形的个数
for(int i=n-1;i>=0;i--){
liml+=(1<<n-i)-1;
limu+=sam*Cut(i);
sam=(sam-1)*2+5;
if(liml<=k && k<=limu+liml) //是否在范围内
return i;
if(k<liml) return -1;
}
}
return -1;
}
int main(){
int cas;scanf("%d",&cas);
while(cas--){
int n;ll k;
scanf("%d%lld",&n,&k);
int res=Solve(n,k);
if(res==-1) printf("NO\n");
else printf("YES %d\n",res);
}
return 0;
}

\(\mathfrak{THE\ END}\)

\(Thanks\ for\ reading!\)

没看懂的可以在 \(lucky\_glass@foxmail.com\) 随便问~

竞赛题解 - [CF 1080D]Olya and magical square的更多相关文章

  1. Codeforces Round #524 (Div. 2) D. Olya and magical square

    D. Olya and magical square 题目链接:https://codeforces.com/contest/1080/problem/D 题意: 给出一个边长为2n的正方形,每次可以 ...

  2. 竞赛题解 - CF Round #524 Div.2

    CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...

  3. CF1080D Olya and magical square

    思路: 构造. 实现: #include <bits/stdc++.h> using namespace std; typedef long long ll; ll sum[]; int ...

  4. codeforces round#524 D - Olya and magical square /// 大概算是数学规律题?

    题目大意: t 个测试用例  (1≤t≤103) 给定n k  (1≤n≤10^9,1≤k≤10^18) 表示有一个边长为2^n的正方形格子 每次操作只能将一个格子切割为左上左下右上右下的四等分格子 ...

  5. 《ACM国际大学生程序设计竞赛题解Ⅰ》——基础编程题

    这个专栏开始介绍一些<ACM国际大学生程序设计竞赛题解>上的竞赛题目,读者可以配合zju/poj/uva的在线测评系统提交代码(今天zoj貌似崩了). 其实看书名也能看出来这本书的思路,就 ...

  6. 竞赛题解 - Karp-de-Chant Number(BZOJ-4922)

    Karp-de-Chant Number(BZOJ-4922) - 竞赛题解 进行了一次DP的练习,选几道题写一下博客~ 标签:BZOJ / 01背包 / 贪心 『题目』 >> There ...

  7. 竞赛题解 - Broken Tree(CF-758E)

    Broken Tree(CF-758E) - 竞赛题解 贪心复习~(好像暴露了什么算法--) 标签:贪心 / DFS / Codeforces 『题意』 给出一棵以1为根的树,每条边有两个值:p-强度 ...

  8. 竞赛题解 - Palisection(CF-17E)

    Palisection(CF-17E) - 竞赛题解 Manacher学到一定程度,也需要练一下有趣的题了-- (这是多老的题了 \(QwQ\))[传送门] 『题意』 给出一个字符串,求总共有多少对不 ...

  9. 竞赛题解 - NOIP2018 保卫王国

    \(\mathcal{NOIP2018}\) 保卫王国 - 竞赛题解 按某一个炒鸡dalao名曰 taotao 的话说: \(\ \ \ \ \ \ \ \ \ "一道sb倍增题" ...

随机推荐

  1. easyui grid 里的可编辑text 加清空图标

    $.extend($.fn.datagrid.defaults.editors, { text: { init: function (container, options) { var _opt = ...

  2. GeoServer中WMS、WFS的请求规范(转载)

    1.背景 1.1WMS简介 Web地图服务(WMS)利用具有地理空间位置信息的数据制作地图.其中将地图定义为地理数据可视的表现.这个规范定义了三个操作:GetCapabitities返回服务级元数据, ...

  3. shell 脚本解压war包+备份+tomcat自动关闭+启动

    公司的开发环境每次替换war包时候,老是需要重新上传并且手动解压,然后再去重启tomcat.觉得这样子太麻烦了,于是写了一个shell脚本,自动解压+备份+tomcat自动关闭+启动.代码如下: #关 ...

  4. 数据库聚焦与非聚焦索引 事务处理 redis innodb引擎(九)

    1 数据库事务处理 一个数据库事务通常包含对数据库进行读或写的一个操作序列 . 当一个事务被提交给了DBMS(数据库管理系统),则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库 ...

  5. 【Leetcode】【Medium】Rotate Image

    You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). ...

  6. 【源码分析】cocos2dx的Action

    第一次去学习Action,总会找到一篇入门的帖子(官网:http://cn.cocos2d-x.org/article/index?type=cocos2d-x&url=/doc/cocos- ...

  7. python全栈学习笔记(一)网络基础之网络协议篇

    阅读目录 一.操作系统基础 二.网络通信原理 2.1 互联网的本质就是一系列的网络协议 2.2 osi七层协议 2.3 tcp/ip五层模型讲解 2.3.1 物理层 2.3.2 数据链路层 2.3.3 ...

  8. 【2D游戏引擎】那些年对游戏对象的思考

    WIP源代码: Github OSC镜像 对象系统以对象为中心,对象系统的最基本设计策略是基于组件的设计.对象系统将尽量避免使用继承方式来拓展游戏对象,恰当的使用Mix-in来来最属性做拓展,单个属性 ...

  9. Apache PredictionIO在Docker上的搭建及使用

    1.Apache PredictionIO介绍 Apache PredictionIO 是一个孵化中的机器学习服务器,它可以为为开发人员和数据科学家创建任何机器学习任务的预测引擎.官方原文: Apac ...

  10. How to update BOL entity property value via ABAP code

    Suppose I have one product with ID I042416 which could be found in CRM WebClient UI: I would like to ...