洛谷P3674 小清新人渣的本愿(莫队)

传送门

由乃tql……

然后抄了一波zcy大佬的题解

我们考虑把询问给离线,用莫队做

然后用bitset维护,每一位代表每一个数字是否存在,记为$now1$

然后再记录一个$now1$的反串$now2$(就是每一位代表的是$N-x$),干吗用等下说

1操作的话,因为每一个位置代表一个数字,如果存在$z-y=x$,可以转化为同时存在$z$和$z-x$,那么把$now1$左移$x$位并与$now1$做$&$运算,看看是否等于$0$,如果不是说明不存在

2操作的话,$now2$中的$y'$代表数字$N-y$,然后求是否存在$z+y=x$,也就是求是否同时满足$now1$中有$z$和$now2$中有$y'$,带进前面的式子里,$N-y'+z=x,z-y'=x-N$,然后就转化成和上面一样了,那么只要把$now2$右移$N-x$位并与$now1$做$&$运算就行了

3操作的话,我们可以考虑枚举约数(总共是$sqrt {n}$个,时间足够),然后在$now1$里每一次查询即可

顺带一提,代码里bitset中的any返回是否有1

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<bitset>
 7 using namespace std;
 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
 9 char buf[1<<21],*p1=buf,*p2=buf;
10 inline int read(){
11     #define num ch-'0'
12     char ch;bool flag=0;int res;
13     while(!isdigit(ch=getc()))
14     (ch=='-')&&(flag=true);
15     for(res=num;isdigit(ch=getc());res=res*10+num);
16     (flag)&&(res=-res);
17     #undef num
18     return res;
19 }
20 const int N=100000;
21 struct node{
22     int k,l,r,x,id;
23 }q[N+5];
24 int m,n,l,r,s;
25 int a[N+5],c[N+5],ans[N+5],rt[N+5];
26 bitset<N+5> now1,now2;
27 inline int operator <(node x,node y){
28     return rt[x.l]==rt[y.l]?rt[x.l]&1?x.r<y.r:x.r>y.r:rt[x.l]<rt[y.l];
29 }
30 inline void init(){
31     n=read(),m=read(),s=sqrt(n);
32     for(int i=1;i<=n;++i) a[i]=read(),rt[i]=(i-1)/s+1;
33     for(int i=1;i<=m;++i){
34         q[i].k=read(),q[i].l=read(),q[i].r=read();
35         q[i].x=read(),q[i].id=i;
36     }
37     sort(q+1,q+1+m);l=1,r=0;
38 }
39 inline void add(int x){if(c[x]++==0)now1[x]=1,now2[N-x]=1;}
40 inline void del(int x){if(--c[x]==0)now1[x]=0,now2[N-x]=0;}
41 int main(){
42     init();
43     for(int i=1;i<=m;++i){
44         while(l<q[i].l) del(a[l++]);
45         while(l>q[i].l) add(a[--l]);
46         while(r>q[i].r) del(a[r--]);
47         while(r<q[i].r) add(a[++r]);
48         int k=q[i].k,x=q[i].x;
49         switch(k){
50             case 1:{
51                 if((now1&(now1<<x)).any())
52                 ans[q[i].id]=1;
53                 break;
54             }
55             case 2:{
56                 if((now1&(now2>>(N-x))).any())
57                 ans[q[i].id]=1;
58                 break;
59             }
60             case 3:{
61                 for(int j=1;j*j<=x;++j)
62                 if(!(x%j))
63                 if(now1[j]&&now1[x/j]){
64                     ans[q[i].id]=1;break;
65                 }
66                 break;
67             }
68         }
69     }
70     for(int i=1;i<=m;++i)
71     puts(ans[i]?"hana":"bi");
72     return 0;
73 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9529091.html