由乃在自己的农田边散步,她突然发现田里的一排玉米非常的不美。这排玉米一共有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. Selenium基础知识(六)下拉列表定位

    1.下拉列表定位 要选择下拉列表中的元素,要先定位到,下拉列表元素,然后可以通过xpath去点击,表内内容 例如,百度搜索-->百度设置-->搜索设置-->选择下拉列表框内" ...

  2. java随机排座位

    //打乱学生顺序 Collections.shuffle(); 容我记个单词 peer: vi.凝视; 盯着看; 隐退,若隐若现; 同等,比得上;n.同辈,同等的人; 贵族; 同伴,伙伴;adj.贵族 ...

  3. UML学习笔记(五)--顺序图

    顺序图是用来描述对象自身及对象间信息传递顺序的视图.它用来表示用例中的行为顺序.当执行一个用例行为时,顺序图中的每条消息对应了一个类操作或状态机中引起转换的触发事件.它着重显示了参与相互作用的对象和所 ...

  4. bat cmd 删除文件或文件夹 删除注册表

    @echo off rd "C:\Documents and Settings\Administrator\桌面\新建文件夹" del 是用来删除文件的,删除文件夹的命令是rd 注 ...

  5. .net中ashx文件有什么用?功能有那些,一般用在什么情况下?

    .ashx是“一般处理文件”.和aspx类似.但是这种文件要比aspx这种前台页面文件内容简单轻巧..ashx不提供前台展示的功能.也可以说它结合了.cs类文件而且又可以提供给.aspx文件做UI层的 ...

  6. [ English ] Ping sb.

    What does "Ping Me" mean?   Recently, when I asked a colleague to ping me, he responded wi ...

  7. 04-树6 Complete Binary Search Tree(30 分)

    title: 04-树6 Complete Binary Search Tree(30 分) date: 2017-11-12 14:20:46 tags: - 完全二叉树 - 二叉搜索树 categ ...

  8. Discuz-阅读权限

    设置用户浏览帖子或附件的权限级别,范围 0-255,0 为禁止用户浏览任何帖子或附件. 当用户的阅读权限小于帖子或附件的阅读权限许可(默认时为 1)时, 用户将不能阅读该帖子或下载该附件

  9. jQuery文档操作--append()、prepend()、after()和before()

       append(content|fn)  概述 向每个匹配的元素内部追加内容,这个操作与对指定的元素执行appendChild方法,将它们添加到文档中的情况类似 参数    content  要追 ...

  10. Tornado安装

    Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其 非阻塞的方式和对 epoll 的运用,Tornado ...