点此看题面

大致题意: 给你一段序列,每次询问一段区间内是否存在两个数的差或和或积为\(x\)。

莫队算法

看到区间询问+可以离线,首先想到了莫队啊。

但是,在较短的时间内更新信息依然比较难以实现。

于是,我们就要考虑用\(bitset\)了。

关于\(bitset\)

这应该是我第一次使用\(bitset\)吧,所以简单介绍一下它的使用方式。

其作用就相当于存储一个特别大的二进制数。可以把它看成一个\(bool\)数组来使用。

它的好处就在于,它可以直接进行\(\&,|,\text{^},<<,>>\)等各种位运算操作。

它有一个比较常用的函数:\(any()\),用于判断该\(bitset\)是否有某个元素值为\(1\)。

另外,还有一个函数\(count()\)是统计有几个\(1\)。

实际上,了解了这些,我们就可以用\(bitset\)来做这题了。

大致思路

考虑开两个\(bitset\):\(s1\)和\(s2\),其中\(s1_i\)表示值为\(i\)的元素是否存在,\(s2_i\)表示值为\(N-i\)的元素是否存在。

这样一来,似乎就不难处理差值的操作了,答案就是\((s1\&(s1<<x)).any()\),这还是比较好理解的,即判断是否有一个数和比它大\(x\)的数同时存在。

同理可得,和的操作答案就是\((s1\&(s2>>N-x)).any()\)。

对于积的操作就略麻烦了一点,需要枚举因数\(j\),然后判断\(j\)和\(\frac xj\)是否同时存在即可,这个操作是\(O(\sqrt x)\)的。

具体实现可见代码。

代码

#include<bits/stdc++.h>
#define N 100000
#define abs(x) ((x)<0?-(x):(x))
using namespace std;
int n,query_tot,a[N+5];
class Class_FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
char ch,*A,*B,Fin[Fsize];
public:
Class_FIO() {A=B=Fin;}
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));}
}F;
class Class_CaptainMotao//莫队
{
private:
int block_size,ans[N+5],cnt[N+5];bitset<N+5> s1,s2;
inline void Add(int x) {if(!cnt[a[x]]++) s1[a[x]]=s2[N-a[x]]=1;}//新加一个元素
inline void Del(int x) {if(!--cnt[a[x]]) s1[a[x]]=s2[N-a[x]]=0;}//删除一个元素
public:
struct Query
{
int l,r,val,op,pos,bl;
inline friend bool operator < (Query x,Query y) {return x.bl^y.bl?x.bl<y.bl:(x.bl&1?x.r<y.r:x.r>y.r);}
}q[N+5];
inline void Solve()
{
int i,j,L=1,R=0;
for(block_size=sqrt(n),i=1;i<=query_tot;++i) F.read(q[i].op),F.read(q[i].l),F.read(q[i].r),F.read(q[i].val),q[q[i].pos=i].bl=(q[i].l-1)/block_size+1;//读入
for(L=1,R=0,sort(q+1,q+query_tot+1),i=1;i<=query_tot;++i)
{
while(R<q[i].r) Add(++R);while(L>q[i].l) Add(--L);while(R>q[i].r) Del(R--);while(L<q[i].l) Del(L++);
switch(q[i].op)
{
case 1:ans[q[i].pos]=(s1&(s1<<q[i].val)).any();break;//对于差的操作
case 2:ans[q[i].pos]=(s1&(s2>>N-q[i].val)).any();break;//对于和的操作
case 3:for(j=1;1LL*j*j<=q[i].val&&!ans[q[i].pos];++j) !(q[i].val%j)&&s1[j]&&s1[q[i].val/j]&&(ans[q[i].pos]=1);break;//对于积的操作
}
}
for(i=1;i<=query_tot;++i) puts(ans[i]?"yuno":"yumi");//输出答案
}
}C;
int main()
{
register int i;
for(F.read(n),F.read(query_tot),i=1;i<=n;++i) F.read(a[i]);
return C.Solve(),0;
}

最新文章

  1. js的继承
  2. 【leetcode】Excel Sheet Column Title &amp; Excel Sheet Column Number
  3. poj1236Network of Schools Tarjan裸题
  4. MFC:在OnInitDialog 里面关闭窗体
  5. spring listener监听器
  6. ZOJ 3781 Paint the Grid Reloaded(BFS)
  7. Jquery_Ajax GET方式传递文本
  8. Sql Server中通配符
  9. js怎样生成json的数据
  10. JAVA采用JDBC连接操作数据库详解
  11. ZED 相机 &amp;&amp; ORB-SLAM2安装环境配置与ROS下的调试
  12. 什么是BSD?
  13. Makefile的obj-y 和 obj-m
  14. FFMPEG结构体分析:AVIOContext
  15. 加密:HashUtils,RSAUtil,AESUtils
  16. dp 二维乃至多维背包
  17. 第一阶段——站立会议总结DAY09
  18. 基础001_Xilinx V7资源
  19. Python 获取秒级时间戳与毫秒级时间戳
  20. D. Dog Show 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred)

热门文章

  1. Nginx + Tomcat7 + redis session一致性问题
  2. 《OD学spark》20161022
  3. Bloomberg 专线配置问题
  4. luogu4168蒲公英(区间众数)
  5. 浏览器Quirksmode(怪异模式)与标准模式
  6. C 语言实例 - 计算标准偏差
  7. OJDBC版本区别:ojdbc14.jar,ojdbc5.jar和ojdbc6.jar的区别
  8. thinphp5会员注册邮箱验证
  9. 译——meta viewport
  10. 学习:数学----gcd及扩展gcd