[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 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...
随机推荐
- leetcode_1039. Minimum Score Triangulation of Polygon_动态规划
https://leetcode.com/problems/minimum-score-triangulation-of-polygon/ 题意:给定一个凸的N边形(N<=50),每个顶点有一个 ...
- aapt环境变量配置
D:\android-sdk_r24.4.1-windows\android-sdk-windows\build-tools\28.0.2 将aapt路径添加到path中, 打开cmd 输入aapt
- JVM的异常体系
任何程序都追求正确有效的运行,除了保证我们代码尽可能的少出错之外,我们还要考虑如何有效的处理异常,一个良好的异常框架对于系统来说是至关重要的.最近在采集框架的时候系统的了解一边,收获颇多,特此记录相关 ...
- vue 数据没有驱动视图?
Part.1 问题 数据改变,视图却没有根据数据而改变. 原因在于,数据并不在 vue 监听范围之内,vue 只对事先在 data 中声明的变量丶对象等类型数据进行监听 Part.2 例子 < ...
- 在移动端实现1px的边框
由于分辨率 DPI 的差异,高清手机屏上的 1px 实际上是由 2×2 个像素点来渲染,有的屏幕甚至用到了 3×3 个像素点 所以 border: 1px 在移动端会渲染为 2px 的边框 与设计图产 ...
- 题目:企业发放的奖金根据利润提成。 利润(I)低于或等于10万元时,奖金可提10%; 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%; 20万到40万之间时,高于20万元的部分,可提成5%; 40万到60万之间时高于40万元的部分,可提成 3%; 60万到100万之间时,高于60万元的部分,可提成1.5%; 高于100万元时,超过
题目:企业发放的奖金根据利润提成. 利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成7.5%: 20万到 ...
- Map与对象关系的思考之P1563玩具谜题
P1563 玩具谜题 结论: map在一些情况有种"对象"的意味,在JSON中,对象可以用K-V格式存储:mybatis中参数是map或者对象都可以实现解析...k-v格式的数据存 ...
- codevs 2853 方格游戏--棋盘dp
方格游戏:http://codevs.cn/problem/2853/ 这和传纸条和noip方格取数这两个题有一定的相似性,当第一眼看到的时候我们就会想到设计$dp[i][j][k][l]$(i,j表 ...
- UVA-1625-Color Length(DP LCS变形)
Color Length(UVA-1625)(DP LCS变形) 题目大意 输入两个长度分别为n,m(<5000)的颜色序列.要求按顺序合成同一个序列,即每次可以把一个序列开头的颜色放到新序列的 ...
- 枚举为何不能设置成public?
听到测试与开发争论,为何枚举不能用public,用public怎么了?对于这个我也不知道到底能不能用,于是就去查了查资料. 解答: 枚举被设计成是单例模式,即枚举类型会由JVM在加载的时候,实例化枚举 ...