并不对劲的复健训练-p3674
题目大意
给出序列$ a_1,...,a_n $ ( $ n\leq10^5,a\leq 10^5 $ ),有\(m\) ( \(m\leq 10^5\))个以下三类询问:
(1)给出\(l,r,k\)(\(k\leq 10^5\)),问是否存在\(x,y\)使\(x\in[l,r],y\in[l,r],a_x-a_y=k\)
(2)给出\(l,r,k\)(\(k\leq 10^5\)),问是否存在\(x,y\)使\(x\in[l,r],y\in[l,r],a_x+a_y=k\)
(3)给出\(l,r,k\)(\(k\leq 10^5\)),问是否存在\(x,y\)使\(x\in[l,r],y\in[l,r],a_x\times a_y=k\)
题解
发现\(a、k\)的值域较小,而且没有修改或强制在线,考虑莫队。
维护表示每个值在当前区间中是否存在的bitset,记为\(c\)。
对于(1)操作,将式子变形为\(a_x=a_y+k\),判断\((c<<k)| c\)中第\(k\)位是否为1
对于(2)操作,将式子变形为\(a_x=k-a_y\),发现\(-a_y\)不好直接算,但是可以维护\((10^5-a_y)\),使式子变为\(a_x=(10^5-a_y)-10^5+k\),记\((10^5-a_y)\)为\(d\),判断\((d>>(10^5-k))|c\)中第\(k\)位是否为1
对于(3)操作,难以变形,可以考虑把\(k\)拆成\(\sqrt k\)个约数,判断\(\sqrt k\)个约数中是否有存在于\(a_l,...,a_r\)的。这样听上去是 莫队的时间复杂度\(\times \sqrt k=n^2\)级别的。但是发现这么写的代码长这样:
rep i 1 to m
移动左右端点;
判断根号k个约数;
所以判断约数的 \(\sqrt k\)和莫队的\(\sqrt n\)是相加的关系。
代码
#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k])
#define maxn 100007
#define maxk 100000
#define LL long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
bitset<100001>now,pnow;
int a[maxn],n,m,num[maxn],ans[maxn],blo=300;
struct quest{int f,l,r,x,id;}q[maxn];
bool cmp(quest x,quest y){return (x.l/blo==y.l/blo)?(x.r<y.r):(x.l<y.l);}
void add(int id,int f)
{
num[a[id]]+=f;
if(f==1&&num[a[id]]==1){now[a[id]]=1,pnow[maxk-a[id]]=1;}
if(f==-1&&!num[a[id]]){now[a[id]]=0,pnow[maxk-a[id]]=0;}
}
int main()
{
n=read(),m=read();
rep(i,1,n)a[i]=read();
rep(i,1,m)q[i].f=read(),q[i].l=read(),q[i].r=read(),q[i].x=read(),q[i].id=i;
int nowl=1,nowr=1;num[a[1]]=1,now[a[1]]=1,pnow[maxk-a[1]]=1;
sort(q+1,q+m+1,cmp);
rep(i,1,m)
{
while(nowl<q[i].l){add(nowl,-1),nowl++;}
while(nowr>q[i].r){add(nowr,-1),nowr--;}
while(nowl>q[i].l){nowl--,add(nowl,1);}
while(nowr<q[i].r){nowr++,add(nowr,1);}
if(q[i].f==1){if(((now<<q[i].x)&now).any())ans[q[i].id]=1;}
else if(q[i].f==2){if(((pnow>>(maxk-q[i].x))&now).any())ans[q[i].id]=1;}
else
{
int lim=sqrt(q[i].x);
rep(j,1,lim)if(q[i].x%j==0&&now.test(j)&&now.test(q[i].x/j)){ans[q[i].id]=1;break;}
}
}
rep(i,1,m)puts(ans[i]?"hana":"bi");
return 0;
}
一些感想
之前轻视bitset的人被bitset教做人了
bitset常用操作:
#include<bitset>//bitset的头文件
bitset<6342>a; //开一个下标从0~6341的bitset
a[63]=1,a[42]=0,a.set(63,1),a.set(42,0),a.reset(42);//赋值
a.set(),a.reset();//全变成1或全变成0
((a<<634)|(a>>23)).any();//bitset可以直接进行位运算,any()返回是否存在一位是1
a.none(),a.all(),a.test(5);//是否任意一位都为0;是否任意一位都为1;是否第5位为1
a.flip(32),a[32].flip();//翻转第32位
a.flip();//翻转全部
a.count(),a.size();//返回一共有几位是1;返回一共有几位
a.to_string(),a.to_ulong(),a.to_ullong();//把bitset变成string;unsigned long;unsigned long long
并不对劲的复健训练-p3674的更多相关文章
- 并不对劲的复健训练-CF1187D
题目大意 有两个长度为\(n\)的序列\(a_1,...,a_n\),\(b_1,...,b_n\)(\(a,b\leq n\leq 3\times 10^5\) ).一次操作是选取 \([l,r]\ ...
- 并不对劲的复健训练-bzoj5250:loj2473:p4365:[九省联考2018]秘密袭击
题目大意 有一棵\(n\)(\(n\leq 1666\))个点的树,有点权\(d_i\),点权最大值为\(w\)(\(w\leq 1666\)).给出\(k\)(\(k\leq n\)),定义一个选择 ...
- 并不对劲的复健训练-bzoj5339:loj2578:p4593:[TJOI2018]教科书般的亵渎
题目大意 题目链接 题解 先将\(a\)排序. \(k\)看上去等于怪的血量连续段的个数,但是要注意当存在\(a_i+1=a_{i+1}\)时,虽然它们之间的连续段为空,但是还要算上:而当\(a_m= ...
- 并不对劲的复健训练-CF1205B Shortest Cycle
题目大意 有\(n\)(\(n\leq 10^5\))个数\(a_1,...,a_n\)(\(a\leq 10^{18}\)).有一个图用这个方法生成:若\(a_i\)按位与\(a_j\)不为0,则在 ...
- 并不对劲的复健训练-p5212 SubString
题目大意 有一个串\(s\),一开始只知道它的一个前缀.有\(q\)(\(q\leq 10^4\))个操作,操作有两种:1.给一个字符串,表示\(s\)(\(s\)总长\(\leq 6\times 1 ...
- 并不对劲的复健训练-bzoj5249:loj2472:p4364[2018多省联考]IIIDX
题目大意 给出\(n,k,d_1,...,d_n\)(\(n\leq 5\times 10^5,1<k\leq 10^9,d\leq 10^9,k\in R\)).有一个满足 对于每个点\(i\ ...
- 并不对劲的复健训练-bzoj5253:loj2479:p4384:[2018多省联考]制胡窜
题目大意 给出一个字符串\(S\),长度为\(n\)(\(n\leq 10^5\)),\(S[l:r]\)表示\(S_l,S_{l+1}...,S_r\)这个子串.有\(m\)(\(m\leq 3\t ...
- 并不对劲的复健训练-bzoj5301:loj2534:p4462 [CQOI2018]异或序列
题目大意 给出一个序列\(a_1,...,a_n\)(\(a,n\leq 10^5\)),一个数\(k\)(\(k\leq 10^5\)),\(m\)(\(m\leq10^5\))次询问,每次询问给\ ...
- 2019NOIP算法复健+学习
前言: 原本因为kma太弱,很多算法没学学了也不会用,打算设置密码给自己看.后来想了想,觉得也没有必要,既然决定了要学些东西到脑子里,就没什么好丢人的. 注:"×"意为完全没学,& ...
随机推荐
- laravel 链式组合查询数据
laravel 链式组合查询数据 一.总结 一句话总结: - 就是链式操作的基本操作,因为返回的都是一直可以进行链式操作的对象,所以我们接收返回的对象即可 - $result = DB::table( ...
- CSS3 新特性
~平时喜欢逛博客,看别人的学习总结和遇到的问题解决办法,恰好最近在做书签整理,翻到了之前一个前辈移动前端的总结,所以我就按他的总结模块对自己的知识进行了梳理,不过由于都是手写的,为了方便,下面的都是平 ...
- 初写C#的小总结
虽然大学学过很多计算机语言,但是现在工作是前端,一个刚入行的前端菜鸟,之前对于后台完全零接触,但是最近有个项目,我也是第一次真正接触C#,中间遇到了一些小问题,就做个总结记录下,真的是超级简单的小知识 ...
- vue如何动态绑定v-model
如图所示有三个字段要从弹出的输入框取值点击字段会弹出上面的弹窗,输入input会响应变化,比如点击身高,弹出输入框,输入值后身高后面会跟着一个同样的值点击体重,弹出输入框,输入值后体重后面会跟着一个同 ...
- JDK与CGlib动态代理的实现
应用的原型为 执行者:房屋中介Agency(分为JDKAgency.CGlibAgency) 被代理对象:程序员Programmer 被代理对象的实现接口:租户Tenement(CGlibAgency ...
- 解决 无法启动此程序,因为计算机中丢失opencv_world341.dll。请尝试重新安装改程序已解决此问题
在运行OpenCV程序时报错:“无法启动此程序,因为计算机中丢失opencv_world341.dll.请尝试重新安装改程序已解决此问题”. 解决方法 我的bin目录是 D:\opencv\build ...
- Android 关于 CountDownTimer onTick() 倒计时不准确问题源码分析
一.问题 CountDownTimer 使用比较简单,设置 5 秒的倒计时,间隔为 1 秒. final String TAG = "CountDownTimer"; * , ) ...
- sqlserver创建链接服务器连接sqlserver脚本
示例: EXEC sp_addlinkedserver @server='MyLinkServer', --链接服务器别名 @srvproduct='', @provider='SQLOLEDB', ...
- acl设置问题
在学习nfs服务配置的时候用到了acl规则(服务配置文件权限设置可写,但是由于客户端映射,不能写入,所以要设置系统权限),但是遇到了一个小小的问题:一.当使用-x选项取消规则的时候,再次查看权限后面仍 ...
- python3.7与pyspider的坑
网络上安装pyspider的坑有很多,但都不如我今天的大,困扰了我几天,终于解决了 Traceback (most recent call last): File "/ffk_learn/s ...