P6429 [COCI2008-2009#1] JEZ 题解
题目传送门:Click。
更好地观感:Click(进入速度玄学)
某蒟蒻看见这道题,想了足足一个晚上,过后茅塞顿开,故作此篇。
感谢神犇的题解,思路基本相同,补充了一些自己的想法或这片题解可能没有注意到的细节。
看题目数据范围:\(1 \leqslant r,c \leqslant 10^6,1 \leqslant k \leqslant 10^{12}\),显然打暴力 \(\mathcal{O}(rc)\) 的时间复杂度是行不通的。必须做到近似于 \(\mathcal{O}(r)\) 的时间复杂度。
观察题目:题目中说:当 \(x+y=x \oplus y\) 时,这个格子是灰色的。而最后所求的答案就是走过的灰色的格子数,很容易想到斜着划分所有的格子,每一组的格子中的任意一个格子 \((x,y)\) 都满足 \(x+y=S\),其中 \(S\) 是不变的。如下图:(图可能有点丑,仅做示意)
接下来,我们针对某个特定的 \(S\) 进行考虑。设有一组 \((x,y)\),那么 \(x \oplus y=S\) 必然满足:\(S\) 二进制上的第 \(x\) 位为 \(1\),则 \(x\) 与 \(y\) 的二进制第 \(x\) 位上必然不同;而当 \(S\) 二进制上的第 \(x\) 位为 \(0\),那么 \(x\) 与 \(y\) 二进制第 \(x\) 位上必然相同。
再来考虑加法。首先看 \(S\) 二进制位的最后一个 \(1\),发现它有两种情况,通过后两位进位,或是由 \(x,y\) 中一个 \(0\) 一个 \(1\) 相加而成。
当它是通过后两位进位而成时,则 \(x,y\) 该位上相同则无法满足异或;不同,则无法满足相加(因为有进位)。(见下图 1)
而它是由更前面的某一位 \(0\) 对应的 \(x,y\) 中的 \(1\),也无法满足要求。(见下图 2)
对于一个 \(S\),我们可以把它分为若干如上形式的二进制段,也可得出相通的结论。综上,在 \(S\) 的每一位 \(0\) 上,\(x\) 与 \(y\) 同为 \(0\) ;否则,\(x,y\) 有且仅有一个 \(1\)。
从这一点入手,统计某一斜行(由于斜行上各自数量可能不确定,我们这里用两个数确定一斜行 \((x,y)\) 表示从 \((0,y)\) 走到 \((x,y-x)\))上有多少个灰色格子(即 \(S=y\)),我们可以知道有一个 \(x^\prime \leqslant x\),其中 \(x^\prime\) 二进制上的每一位 \(1\),都对应了 \(x\) 与 \(y\) 上公共的 \(1\)。在这个 \(x^\prime\) 中,(对于一对二元组 \((p,q)\),这一步相当于枚举 \(x\) 的二进制位)我们可以知道 \(p\) 可以在这一位上取 \(1\)(\(q\) 取 \(0\)),或者取 \(0\)(\(q\) 相反)。而对于 \(y\) 某二进制位上为 \(1\),而 \(x\) 该二进制位上不为 \(1\),那么只可能 \(q\) 上取 \(1\),而 \(p\) 上为 \(0\)。
简单地说,就是将 \(y\) 分解成若干段形如 \(\texttt{1000...}\) 的二进制段,然后判断这些“段”与 \(x\) 是否对应。如果其最高位 \(1\) 与 \(x\) 对应,那么说明这一位可以 \(1\),答案加上后面的几段(注意!这里并不要求与 \(x\) 对应!)分别取 \(0\) 或 \(1\) 的总方案数。当然,这样算会少算一种情况,即所有对应二进制段上都取了 \(0\)。
理解了这个规律,我们可以写出这样一个用来统计某一斜行上灰色格子数量的函数:
ll type[64];
ll counting(ll x,ll y) {
ll res=1LL,cnt=0;
for(;y;res<<=1,y>>=1)
if(y&1) type[++cnt]=res;
res=0;
for(ll i=cnt;i>0;--i)
if(x-type[i]>=0) x-=type[i],res|=(1<<i-1);
return res+1;
}
解释说明:\(\operatorname{type}_i\) 表示 \(y\) 从高到低第 \(i\) 个 \(1\) 的权值。由于下标就相当于第几段,然后直接一边分解 \(x\) 一边计算答案就行了。1<<i-1
表示第 \(i\) 段后面有 \(i-1\) 段,每段取或不取的总方案数为 \(2^{i-1}\),由于每个二进制位都不会重复,可以直接用 |=
运算。
最后回到问题,统计走 \(k\) 步走过的灰色格子数,可以先统计从如下图红色部分的斜行的灰色格子数,然后统计如下图绿色部分的灰色格子数,累加走过的格子。当走不完某一斜行时,暴力模拟一下就可以了。这里细节有点多,就不赘述了。
(其中灰色部分可以帮助统计绿色部分)
完整代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll type[64];
ll counting(ll x,ll y) {
ll res=1LL,cnt=0;
for(;y;res<<=1,y>>=1)
if(y&1) type[++cnt]=res;
res=0;
for(ll i=cnt;i>0;--i)
if(x-type[i]>=0) x-=type[i],res|=(1<<i-1);
return res+1;
}
ll n,m,k;
int main() {
scanf("%lld%lld%lld",&n,&m,&k);
int drct=1;
if(m<n) swap(m,n),drct=0;
ll ans=0,done=0;
for(ll i=0;i<m;++i,drct^=1) {
ll cnt=min(i+1,n);
if(done+cnt<k) done+=cnt,ans+=counting(min(i,n-1),i);
else {
if(drct) for(ll p=min(i,n-1),q=i-min(i,n-1);done<k;--p,++q,++done)
ans+=p+q==(p^q);
else for(ll p=0,q=i;done<k;++p,--q,++done)
ans+=p+q==(p^q);
break;
}
}
if(done==k) {
printf("%lld\n",ans);
return 0;
}
for(int i=1;i<n;++i,drct^=1) {
ll cnt=n-i;
if(done+cnt<k) done+=cnt,ans+=counting(n-1,m+i-1)-counting(i-1,m+i-1);
else {
if(drct) for(ll p=n-1,q=m-n+i;done<k;--p,++q,++done)
ans+=p+q==(p^q);
else for(ll p=i,q=m-1;done<k;++p,--q,++done)
ans+=p+q==(p^q);
break;
}
}
printf("%lld\n",ans);
return 0;
}
完。
P6429 [COCI2008-2009#1] JEZ 题解的更多相关文章
- 1642: 【USACO】Payback(还债)
1642: [USACO]Payback(还债) 时间限制: 1 Sec 内存限制: 64 MB 提交: 190 解决: 95 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 &quo ...
- 题解 P1951 【收费站_NOI导刊2009提高(2)】
查看原题请戳这里 核心思路 题目让求最大费用的最小值,很显然这道题可以二分,于是我们可以二分花费的最大值. check函数 那么,我们该怎么写check函数呢? 我们可以删去费用大于mid的点以及与其 ...
- 【题解】 Luogu P4312 / SP4155 [COCI 2009] OTOCI / 极地旅行社
原题地址:P4312 [COCI 2009] OTOCI / 极地旅行社/SP4155 OTOCI - OTOCI lct入门难度的题,十分弱智(小蒟蒻说lct是什么,能吃吗?) bridge操作判联 ...
- [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)
[BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...
- BZOJ2038:[2009国家集训队]小Z的袜子——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找 ...
- 洛谷 P1950 长方形_NOI导刊2009提高(2) 题解
P1950 长方形_NOI导刊2009提高(2) 题目描述 小明今天突发奇想,想从一张用过的纸中剪出一个长方形. 为了简化问题,小明做出如下规定: (1)这张纸的长宽分别为n,m.小明讲这张纸看成是由 ...
- HDU100题简要题解(2000~2009)
前言(废话): 从11月6号到11月20号,断断续续做了有三个星期,总算整完了,之后会慢慢整理汇总到这里 中间部分用到数学知识的十几道题边学边做直接把我这个数学菜鸟做到怀疑人生 11.6~11.10又 ...
- [题解] 2038: [2009国家集训队]小Z的袜子(hose)
莫队,卡常数 题目地址 思路 设\(\text{Vis[i]}\)为元素\(\text{i}\)在区间\(\text{[L,R]}\)的出现次数 考虑区间\(\text{[L,R]}\)和元素\(\t ...
- 题解 P1944 最长括号匹配_NOI导刊2009提高(1)
栈,模拟 把每个元素逐个入栈 如果和栈顶元素匹配,那么一块弹出去,同时标记这里是可匹配的. 取出连续的,最长的可匹配的序列即可. #include <iostream> #include ...
- 【题解】Inspection UVa 1440 LA 4597 NEERC 2009
题目传送门:https://vjudge.net/problem/UVA-1440 看上去很像DAG的最小路径覆盖QwQ? 反正我是写了一个上下界网络流,建模方法清晰易懂. 建立源$s$,向每个原图中 ...
随机推荐
- <HarmonyOS第一课06>构建更加丰富的页面
视频链接: https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101717497640610394?ha_sou ...
- 想让鸿蒙应用快的“飞起”,来HarmonyOS开发者官网“最佳实践-性能专区”
在鸿蒙应用开发过程中,应用侧流畅运行体验是开发者非常关注的部分.为此,华为HarmonyOS开发者官网推出了"最佳实践-性能专区"(以下简称"性能专区"),通过 ...
- 代码随想录第二十五天 | Leecode 491. 非递减子序列、46. 全排列、47. 全排列 II
Leecode 491. 非递减子序列 题目描述 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 .你可以按 任意顺序 返回答案. 数组中可能含有重 ...
- 【MOOC】华中科技大学计算机组成原理慕课答案-第八章-输入输出系统
应一个同学后台留言,说让我发就发全,那我干脆把剩的这一章测验也发了吧. 以下解析由GPT生成,不保证可读可解释,仅保证答案正确. 单选 1 (单选(2分)) 某中断系统中,每抽取一个输入数据就要中断 ...
- 重磅消息,微软宣布 VS Code Copilot 开源,剑指 Cursor!
前言 微软宣布重磅消息将把 GitHub Copilot Chat 扩展的代码以 MIT 许可证协议开源,然后将扩展中的 AI 功能重构到 VS Code 核心中,这一举措是为了将 VS Code 成 ...
- list.stream笔记-过滤-去重-转map、List等
代码 import vo.PosDataDetailVo; import java.util.*; import java.util.stream.Collectors; public class A ...
- 启智树提高组day4T3 T3(t3.cpp,1s,512MB)
启智树提高组day4T3 T3(t3.cpp,1s,512MB) 题面描述 输入格式 输出格式 样例输入 样例输出 数据范围 题解 task1 暴力dfs 10分 Code 1 #include< ...
- 我们不可能永远都在救火 ——Scrum中技术债务“偿还”指南
技术债务是指开发人员为了加速软件开发,在应该采用最佳方案时进行了妥协,改用了短期内能加速软件开发的方案,以至于未来给自己带来额外的开发负担. 软件工程师 Ward Cunningham首次将技术的复杂 ...
- js判断一个变量是否存在值得简单方法
在编码过程中,有时候我们需要对一个变量判断其是否有值,这里有一种比较不错的方法判断: !!variable //返回True为存在值,返回False为不存在值 注意是双感叹号"!!" ...
- crictl基础操作
# 1. 查看机器上的镜像列表 crictl images ls # 2.删除机器上没用使用的镜像 crictl rmi --prune