由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美。这排玉米一共有N株,它们的高度参差不齐。
由乃认为玉米田不美,所以她决定出个数据结构题
 
这个题是这样的:
给你一个序列a,长度为n,有m次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是
否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ,这三个操作分别为操作1
,2,3选出的这两个数可以是同一个位置的数

Input

第一行两个数n,m
后面一行n个数表示ai
后面m行每行四个数opt l r x
opt表示这个是第几种操作,l,r表示操作的区间,x表示这次操作的x
定义c为每次的x和ai中的最大值,ai >= 0,每次的x>=2n,m,c <= 100000

Output

对于每个询问,如果可以,输出yuno,否则输出yumi

Sample Input

5 5
1 1 2 3 4
2 1 1 2
1 1 2 2
3 1 1 1
3 5 5 16
1 2 3 4

Sample Output

yuno
yumi
yuno
yuno
yumi

  题目大意 (数据结构裸题不需要大意)。(这是由乃OI?)

  显然bitset(别问我怎么知道的)。

  然而考虑分块,MLE?所以果断否决掉。

  是有个基于分块有很省内存的算法?莫队啊,我们只需要2个bitset和一个cnt数组就好了。

  现在来考虑具体的操作。

  1)区间内是否存在两个数差为x。这个很简单,bitset一个基本的应用。bitset维护一个值域,然后将所有数都减去x(相当于将这个bitset右移x位),再看有没有数相等(新bitset按位与旧bitset得到的bitset是否存在某一位为1,调用它的函数any()就好了)

  2)区间内是否存在两个数和为x。考虑a + b = x,加法不是很好处理,就转化成减法,得到a - (-b) = x。因为bitset不支持负数下标,把大小增大常数又变大,所以考虑用2个bitset。新的bitset维护某一个上限加上-b后的值域。查询的时候我们希望将第一个bitset右移x位,显然负数位才有价值,但是右移溢出的比特位会被直接舍去。所以考虑向左移,把右移x后,没有溢出的部分全部删去。这样的话就左移(limit - x)位,在和第二个bitset进行按位与,然后判断是否存在某一位为1。

  3)还是bitset?想多了。。。Tag害死人啊。。值域只有1e5。是不是直接根号大暴力(枚举因子)就完事了?(然后我忘判因子了,就WA了几次)

Code

 /**
* bzoj
* Problem#4810
* Accepted
* Time:13672ms
* Memory:4472k
*/
#include<bits/stdc++.h>
using namespace std;
typedef bool boolean; typedef class Query {
public:
int opt;
int l;
int r;
int x;
int lid;
int id; Query():opt(opt), l(l), r(r), x(x), lid(lid) { } boolean operator < (Query b) const {
if(lid != b.lid) return lid < b.lid;
return r < b.r;
}
}Query; #define limit 100001
int n, m, cs;
int *arr;
bitset<> s, s1, rs;
Query* qs;
inline void init() {
scanf("%d%d", &n, &m);
arr = new int[(n + )];
qs = new Query[(m + )];
cs = sqrt(n + 0.5);
for(int i = ; i <= n; i++)
scanf("%d", arr + i);
for(int i = ; i <= m; i++) {
scanf("%d%d%d%d", &qs[i].opt, &qs[i].l, &qs[i].r, &qs[i].x);
qs[i].lid = qs[i].l / cs, qs[i].id = i;
}
} boolean *res;
int cnt[];
inline void extends(int pos, int val) {
cnt[arr[pos]] += val;
if(cnt[arr[pos]] == ) s[arr[pos]] = , rs[limit - arr[pos]] = ;
if(cnt[arr[pos]] == ) s[arr[pos]] = , rs[limit - arr[pos]] = ;
} inline void solve() {
res = new boolean[(m + )];
sort(qs + , qs + m + );
int mdzzl = , mdzzr = ;
boolean aFlag = false;
for(int i = ; i <= m; i++) {
while(mdzzr < qs[i].r) extends(++mdzzr, );
while(mdzzr > qs[i].r) extends(mdzzr--, -);
while(mdzzl > qs[i].l) extends(--mdzzl, );
while(mdzzl < qs[i].l) extends(mdzzl++, -);
switch(qs[i].opt) {
case :
s1 = (s << qs[i].x) & s;
res[qs[i].id] = s1.any();
break;
case :
s1 = (s << (limit - qs[i].x)) & rs;
res[qs[i].id] = s1.any();
break;
case :
aFlag = false;
for(int j = ; j * j <= qs[i].x; j++)
if((qs[i].x % j == ) && s[j] && s[qs[i].x / j]) {
aFlag = true;
break;
}
res[qs[i].id] = aFlag;
break;
default:
break;
}
}
for(int i = ; i <= m; i++)
puts((res[i]) ? ("yuno") : ("yumi"));
} int main() {
init();
solve();
return ;
}

bzoj 4810 由乃的玉米田 - bitset - 莫队算法的更多相关文章

  1. BZOJ 4810 [Ynoi2017]由乃的玉米田 ——Bitset 莫队算法

    加法和减法的操作都能想到Bitset. 然后发现乘法比较难办,反正复杂度已经是$O(n\log{n})$了 枚举因数也不能更差了,直接枚举就好了. #include <map> #incl ...

  2. 【BZOJ4810】[Ynoi2017]由乃的玉米田 bitset+莫队

    [BZOJ4810][Ynoi2017]由乃的玉米田 Description 由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美.这排玉米一共有N株,它们的高度参差不齐.由乃认为玉米田不美,所 ...

  3. BZOJ 4810 [Ynoi2017]由乃的玉米田 (莫队 + bitset)

    题目链接  BZOJ 4810 首先对询问离线, 莫队算法处理. 首先我们可以用bitset维护处当前区间中是否存在某个数. 对于询问1, 我们可以用 ((f >> q[i].x) &am ...

  4. 【BZOJ4810】[YNOI2017] 由乃的玉米田(莫队+bitset)

    点此看题面 大致题意: 给你一段序列,每次询问一段区间内是否存在两个数的差或和或积为\(x\). 莫队算法 看到区间询问+可以离线,首先想到了莫队啊. 但是,在较短的时间内更新信息依然比较难以实现. ...

  5. BZOJ 4810 [Ynoi2017]由乃的玉米田(莫队+bitset)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4810 [题目大意] 给出一个数列,有三种区间查询, 分别查询区间是否存在两个数乘积为x ...

  6. BZOJ4810 Ynoi2017由乃的玉米田(莫队+bitset)

    多组询问不强制在线,那么考虑莫队.bitset维护当前区间出现了哪些数,数组记录每个数的出现次数以维护bitset.对于乘法,显然应有一个根号范围内的因子,暴力枚举即可.对于减法,a[i]-a[j]= ...

  7. 【BZOJ】3781: 小B的询问(莫队算法)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3781 还能不能再裸点.. #include <cstdio> #include < ...

  8. 【BZOJ】2120: 数颜色 带修改的莫队算法

    [题意]给定n个数字,m次操作,每次询问区间不同数字的个数,或修改某个位置的数字.n,m<=10^4,ai<=10^6. [算法]带修改的莫队算法 [题解]对于询问(x,y,t),其中t是 ...

  9. bzoj 2038 小Z的袜子(hose)(莫队算法)

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 11542  Solved: 5166[Sub ...

随机推荐

  1. cocos2d-x JS 纯代码实现人物头像裁剪

    有时候为了方便会直接用颜色层和过渡层来显示一些信息,但层只有方角没有圆角不太美观,于是我用剪切节点实现了一个圆角层.方便以后使用.   当然,如果使用Cosos Studio 操作会更好一些,省去了坐 ...

  2. JAVA8流操作

    * Stream 的三个操作步骤: * 1创建Stream * 2中间操作 * 3终止操作 package airycode_java8.nice6; import airycode_java8.ni ...

  3. javascript 面向对象之路.1 - 小蜜蜂

    写这个系列文章是想通过几个案例来学习javascript html5 css3,其实这个小游戏谁都能做出来,但对于一个作为后端.net程序员的我来说还是有学习的必要,毕竟javascript的面向对象 ...

  4. notepad怎么把空格替换成回车?

    替换时选中“使用正则表达式”查找里输入\s替换里输入\r然后“全部替换”即可

  5. VS2010 发布网站时文件丢失解决办法

    网站项目中包含了一写rdlc的东西,发布网站选择仅限运行此应用程序所需文件,发布成功后发现这两个文件夹都没发布出来,找了下原因,解决办法是选择文件打开属性窗口找到生成操作,选项选择“内容”,重新发布, ...

  6. Nginx技术研究系列2-基于Redis实现动态路由

    上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...

  7. 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】

    像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...

  8. Spark学习之路 (十二)SparkCore的调优之资源调优

    摘抄自:https://tech.meituan.com/spark-tuning-basic.html 一.概述 在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都 ...

  9. 【Oozie学习之一】Oozie

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 CM5.4 一.简介Oozie由Cloudera公司贡献给A ...

  10. Extjs4前端开发代码规范参考

    准则:  一致性, 隔离与统一管理, 螺旋式重构改进, 消除重复, 借鉴现有方案 1.    保证系统实现的一致性,寻求一致性方案, 相同或相似功能尽量用统一模式处理: 2.    尽可能使用隔离技术 ...