[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 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求, ...
随机推荐
- Java replaceAll不区分大小写
Java 中replaceAll如何忽略大小写呢? 方式一:在正则表达式前面添加(?i) @Test public void test_replaceAll33(){ String input = & ...
- environ - 用户环境(变量)
SYNOPSIS 总览 extern char **environ; DESCRIPTION 描述 变量 environ 指向的是一个叫 'environment'(环境)的字符串数组 (这个变量必须 ...
- ::Sleep(0)的使用
::Sleep(0)的使用 This function causes a thread to relinquish the remainder of its time slice and become ...
- mybatis中配置中引入properties文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
- Linux的Network Tunnel技术
Linux的Network Tunnel技术 概要 Linux上可以使用ip tunnel命令创建多种类型的tunnel. 在 man ip-tunnel 中可以得知以下几种类型的tunnel: MO ...
- 第4节 hive调优:2、数据倾斜
数据的倾斜: 主要就是合理的控制我们的map个数以及reduce个数 第一个问题:maptask的个数怎么定的???与我们文件的block块相关,默认一个block块就是对应一个maptask 第二个 ...
- 用css实现html中单选框样式改变
我们都知道,input的单选框是一个小圆框,不能直接更改样式.但是我们在很多网页中看到的单选框样式可不仅限于默认的那个样式(看上去没啥新意,也比较丑).那么,接下来我将介绍下如何实现该功能. 首先, ...
- 使用scrapy爬取suning
# -*- coding: utf-8 -*- import scrapy from copy import deepcopy class SuSpider(scrapy.Spider): name ...
- 快速简单高效的搭建 SolrCloud 集群
转https://segmentfault.com/a/1190000008634902 集群配置 集群中的每台机器都要按照以下说明进行配置启动 首先到 solr 安装目录的 bin 下,编辑 sol ...
- Farthest Nodes in a Tree (求树的直径)
题目链接,密码:hpu Description Given a tree (a connected graph with no cycles), you have to find the farthe ...