[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 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...
随机推荐
- Javaweb之xml
1 XML概述 1.1 XML是什么? eXtensible Markup Language可扩展标记语言 1.2 XML作用 主要是用于描述数据,而 ...
- Redis杂谈
这是2015年初应邀在南华智闻作技术交流时所作的Redis方面的一个presentation. 因为原件是Keynote格式,已经转成PDF,点击下面链接打开或者下载PDF: Redis 杂谈
- Git理论知识补充
转自: http://www.cnblogs.com/hnrainll/archive/2012/11/13/2768003.html 对于任何一个文件,在 Git 内都只有三种状态:已提交(comm ...
- Docker Hello World容器运行报错的解决办法
费了好大力气从Docker官网下载了Docker Community Editor的安装镜像,Docker.dmg, 总共将近500MB,双击进行安装: 命令行里使用docker version查看版 ...
- Unity3D 在自定义脚本中实现Button组件上的OnClick面板
下述内容不对c#语法做过多讲解,仅对已入门并有兴趣的同学做为学习和拓展的资料 大家在Unity制作的过程中一定都使用过UI功能,那么很多人也一定见过这个面板: 那么我们如何能在自己的脚本中添加上像On ...
- k8s集群之master节点部署
apiserver的部署 api-server的部署脚本 [root@mast-1 k8s]# cat apiserver.sh #!/bin/bash MASTER_ADDRESS=$1 主节点IP ...
- SFM作业
代码:https://github.com/jianxiongxiao/SFMedu PPT:http://3dvision.princeton.edu/courses/SFMedu/slides.p ...
- 天梯赛L1 题解
L1-001 Hello World (5 分) 这道超级简单的题目没有任何输入. 你只需要在一行中输出著名短句“Hello World!”就可以了. AC代码:(直接输出记性) #include & ...
- python TCP协议详解 三次握手四次挥手和11种状态
11种状态解析 LISTEN -------------------- 等待从任何远端TCP 和端口的连接请求. SYN_SENT --------------- 发送完一个连接请求后等待一个 ...
- 【Mysql数据库】知识点总结
本文转载自:http://www.cnblogs.com/tonghun/p/7191131.html 一 数据库常用操作 mysql -u+username -p+password:登陆数据库管理系 ...