[Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)
4722: 由乃
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 360 Solved: 131
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
Yuno Yuno Yuno Yuno Yuki
HINT
分析:
(话说这道题是道卡常题啊!!)
对于数据没有梯度这种东西,还是持有吐槽的态度的……还有常数太大,还好数据水。
好了,先说个题外话:当一个幼儿园有367个小朋友,那么肯定有两个人的生日会在同一天。
为什么要说这个呢?
因为这道题比如我们查询的区间长度为len,那么子区间方案数为2 ^ len,区间值域又为[len,(v + 1) * len],只要使2 ^ len >(v + 1) * len,就一定存在有解的情况(原因如上述题外话)。
解方程:2 ^ len >(v + 1) * len ,解得len最小为 14.
所以只要查询区间长度 len > 13 就一定有解。
那么再来看看区间长度 <= 13的。题目让在大区间内,选两个互不相交的子集相等,可以转换成在大区间里每个数的系数有的为1(选入X集合),有的为0(不选),有的为 -1(选入Y集合);
问是否存在使所有数加起来为0; 因为 2 ^ len 暴力枚举方案 len 是最大为13的,再乘上 m 显然时间是不够的。
我们可以采用二分的思想,先处理完[l,mid]区间。再处理[mid + 1,r]区间,这样 2 ^ 13被划为了 2 * (3 ^ 7),显然降低了很多。但常数还是巨大的(还好数据水)。
这样就处理完第一种查询了。
再来看第二种修改。
我们发现如果每次去乘常数也是巨大的,所以我们会联想到采用lazy标记。但是每次我们只询问叶子结点的值是多少,所以我们只用在询问叶子结点时才释放lazy标记。
再来看看具体操作 a[i] = (a[i]³)^ lazy,我们是不可能暴力去乘的,常数也是巨大的。貌似快速幂也常数大了点(因为调用了乘法,取模)。
我们发现无论再怎么次方,数都是在v以内的。我们可以预先处理出(0 ~ v - 1)的幂的表,这样每次就不用手动去乘了。
处理这个表类似于倍增的思想,我们知道每个数的data[i][j - 1](表示i 的 2 ^ j - 1方的数是多少),就可以通过data[i][j] = data[data[i][j - 1]][j - 1]; 推出data[i][j]。O(nlogn)的预处理。
这样每次下方lazy标记变成了严格的log,而不是像快速幂一样在log上带上大常数。
然后操作一遍就可以了。
二分处理:
因为某G姓男子不懂二分这一块,我只好单独提出来解释一下:
比如说有13个数区间为[2,14],mid 为 8,那么我们会分开处理[2,8]和[9,14]两段区间。
用dfs,枚举有的数系数为1,有的数系数为0,有的数系数为-1。比如说在[2,8],[9,14]这些区间里就有数加减得0,我们是可以输出Yuno的。
没有的话看[2,8]里面出出现过的数是否[9,14]里面也出现过,出现过也可以输出Yuno。
话说某人问题是比如有5个数,999 3 7 4 16。如果我们会去处理[1,3]和[4,5]这两段区间,可是我们的X 和 Y集合是[2,4] 和[5],[2,4]是跨越了mid的。是不会找到的。
我们这样想,如果在处理右区间[4,5]时,我们给[4]这里的数系数赋为-1,是不是就相当于加进了X集合。所以二分是可以处理的
AC代码:
# include <iostream> # include <cstdio> # include <cstring> # include <cstdlib> using namespace std; ; ; int read() { ,f = ; char i = getchar(); ;i = getchar();} + i - ';i = getchar();} return ans * f; } int n,m,v,mid,ol,x,y,d; ],a[N],stack[N],cnt; ],lazy[N << ]; bool flag[N]; void down(int rt){ lazy[rt << ] += lazy[rt]; lazy[rt << | ] += lazy[rt]; lazy[rt] = ; } void push(int &ans,int &r){ ; ){ << j)){ ans = data[ans][j]; r -= ( << j); )return; } j--; } } void updata(int L,int R,int l,int r,int rt){ if(L <= l && r <= R){ lazy[rt]++; return; } if(lazy[rt])down(rt); ; ); ,r,rt << | ); return; } void Query(int L,int l,int r,int rt){ if(l == r){ push(a[L],lazy[rt]); return; } if(lazy[rt])down(rt); ; ); ,r,rt << | ); return; } void init(){ ;i < v;i++){ data[i][] = (i * i % v) * i % v; } ;j <= ;j++){ ;i < v;i++){ data[i][j] = data[data[i][j - ]][j - ]; } } } void dfsl(int u,int dis,bool k){ if(ol)return; ){ if(k){ if(!dis){ ol = true; } && !flag[dis]){flag[dis] = true;stack[++cnt] = dis;} } return; } dfsl(u + ,dis,k); dfsl(u + ,dis + a[u] + ,true); dfsl(u + ,dis - a[u] - ,true); return; } void dfsr(int u,int dis,bool k){ if(ol)return; ){ if(k){ if(!dis){ ol = true; } && flag[dis]){ ol = true; } } return; } dfsr(u + ,dis,k); dfsr(u + ,dis + a[u] + ,true); dfsr(u + ,dis - a[u] - ,true); return; } int main(){ n = read(),m = read(),v = read(); ;i <= n;i++){ a[i] = read(); } init(); ;i <= m;i++){ d = read(),x = read(),y = read(); ){ updata(x,y,,n,); }else { ){ puts("Yuno"); }else { for(int j = x;j <= y;j++){ Query(j,,n,); } mid = (x + y) >> ; ol = ; dfsl(x,,false); dfsr(mid + ,,false); ;i <= cnt;i++){ flag[stack[i]] = false; } if(ol)puts("Yuno");else puts("Yuki"); } } } ; }
[Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)的更多相关文章
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
黑白图像直方图 发布时间: 2017年7月9日 18:30 最后更新: 2017年7月10日 21:08 时间限制: 1000ms 内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...
- [AHOI 2009] 维护序列(线段树模板题)
1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小 ...
- POJ 3468 线段树裸题
这些天一直在看线段树,因为临近期末,所以看得断断续续,弄得有些知识点没能理解得很透切,但我也知道不能钻牛角尖,所以配合着刷题来加深理解. 然后,这是线段树裸题,而且是最简单的区间增加与查询,我参考了A ...
- hdu-1540线段树刷题
title: hdu-1540线段树刷题 date: 2018-10-18 19:55:21 tags: acm 刷题 categories: ACM-线段树 概述 哇,,,这道线段树的题可以说是到目 ...
- hdu-5023线段树刷题
title: hdu-5023线段树刷题 date: 2018-10-18 13:32:13 tags: acm 刷题 categories: ACM-线段树 概述 这道题和上次做的那道染色问题一样, ...
- poj-2777线段树刷题
title: poj-2777线段树刷题 date: 2018-10-16 20:01:07 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道线段树的染色问题,,, ...
- zoj-1610线段树刷题
title: zoj-1610线段树刷题 date: 2018-10-16 16:49:47 tags: acm 刷题 categories: ACM-线段树 概述 这道题是一道简单的线段树区间染色问 ...
- Codeforces Round #393 (Div. 2) (8VC Venture Cup 2017 - Final Round Div. 2 Edition) E - Nikita and stack 线段树好题
http://codeforces.com/contest/760/problem/E 题目大意:现在对栈有m个操作,但是顺序是乱的,现在每输入一个操作要求你输出当前的栈顶, 注意,已有操作要按它们的 ...
- hdu 1754 I Hate It 线段树基础题
Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...
随机推荐
- xcopy递归拷贝
递归拷贝 ::xcopy SOURCE_DIR DES_DIR\ /s SOURCE_DIR后面不需要加反斜杠
- 51nod 1031 骨牌覆盖
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 收藏 关注 在2*N的一个长方形方格中,用一个1*2的骨牌排满方格. 问有多少种不同的排列方法. 例如: ...
- umask命令
umask——显示.设置文件的缺省权限 the user file-creation mask 命令所在路径:Shell内置命令 示例1:显示缺省权限 # umask -S 参数S的作用是以rwx形式 ...
- tomcat 虚拟目录配置
1.虚拟目录优点 原始 拷贝到webapps下,然后启动tomcat,就可以访问webapps下的项目.eclipse配置tomcat的原理也是这种方式. 虚拟目录 定位到eclipse工作目录下,实 ...
- docker的安装及基础操作与镜像构建
仓库配置及安装启动 [root@localhost ~]# yum install -y yum-utils device-mapper-persistent-data lvm2 [root@loca ...
- 关于Java的三种普通排序
首先要知道是哪几种排序 这里我们所说的是 冒泡排序,选择排序以及插入排序 然后要理解大概的排序速度 : 插入<选择<冒泡 下面是代码 大家可以拷贝自己在java环境里运行运行! publi ...
- OpenCV2:总结篇 工具方法函数
一.简介 OpenCV提供了一些工具方法函数来辅助完成图像运算 二.时间相关 1.getTickCount()和getTickFrequency() double tTime; tTime = (do ...
- DNS查询过程
DNS查询过程 假设www.abc.com的主机要查询www.xyz.abc.com的服务器ip地址. 知识点 1.hosts文件:以静态映射的方式提供IP地址与主机名的对照表,类似ARP表 2.域: ...
- Linux磁盘管理及Lvm
1. 硬盘接口 IDE: SATA:常用: SCSI:主要用于高端服务器,linux默认: SAS 2. 硬盘种类 SATA硬盘:串口硬盘,有较强的纠错能力: SCSI 硬盘:默认硬盘: SAS 硬盘 ...
- maven构建springmvc项目
1.Eclipse中 NEW ->OTHER->Maven->maven project 2.选择项目路径 3.选择项目类型->next->输入groupid和artif ...