解题:洛谷3674 小清新人渣的本愿

题面

这题重点不在莫队,在于这个求解方法,挺有意思的

维护一个bitset $stat$表示当前区间的状态,同时反过来(不是通常意义上的反,是从尾到头)维护这个区间的另一状态rsta

对于询问是否有$x$这个差,查询$stat\&(stat<<x)$(之中是否有1)

对于询问是否有$x$这个和,查询$stat\&(rsta>>(Maxn-x))$(Maxn表示最大的数)

对于询问是否有$x$这个积,直接$O(sqrt(x))$枚举

(额外说一句,lxl在讨论里说了维护商的方法:离线后扫一遍(虽然我没听懂))

 1 // luogu-judger-enable-o2
 2 #include<cmath>
 3 #include<cstdio>
 4 #include<cctype>
 5 #include<bitset>
 6 #include<cstring>
 7 #include<algorithm>
 8 using namespace std;
 9 const int N=100005;
10 struct a
11 {
12     int typ,id;
13     int l,r,v,q,ans;
14 }mo[N];
15 bitset<N> stat,rsta; 
16 int n,m,t1,t2,t3,t4,sqr; 
17 int num[N],cnt[N];
18 inline int read()
19 {
20     int ret=0;
21     char ch=getchar();
22     while(!isdigit(ch))
23         ch=getchar();
24     while(isdigit(ch))
25         ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();
26     return ret;
27 }
28 bool cmp(a x,a y)
29 {
30     return x.v==y.v?x.r<y.r:x.v<y.v;
31 }
32 bool com(a x,a y)
33 {
34     return x.id<y.id;
35 }
36 inline void change(int val,int typ)
37 {
38     if(typ)
39     {
40         if(++cnt[val]==1) 
41             stat[val]=true,rsta[N-val]=true;
42     }
43     else 
44     {
45         if(!(--cnt[val]))
46             stat[val]=false,rsta[N-val]=false;
47     }
48 }
49 inline int ask(int typ,int qry)
50 {
51     if(typ==1) return (stat&(stat<<qry)).count();
52     else if(typ==2) return (stat&(rsta>>(N-qry))).count();
53     else 
54     {
55         register int i;
56         for(i=1;i*i<=qry;i++)
57             if((stat[i]&&stat[qry/i])&&qry%i==0) return true;
58         return false;    
59     } 
60 }
61 int main()
62 {
63     register int i;
64     n=read(),m=read(),sqr=sqrt(n);
65     for(i=1;i<=n;i++) num[i]=read();
66     for(i=1;i<=m;i++)
67     {
68         t1=read(),t2=read(),t3=read(),t4=read();
69         mo[i].typ=t1,mo[i].l=t2,mo[i].r=t3,mo[i].q=t4;
70         mo[i].id=i,mo[i].v=(t2-1)/sqr+1;
71     }
72     sort(mo+1,mo+1+m,cmp);
73     register int lp=1,rp=0;
74     for(i=1;i<=m;i++)
75     {
76         while(lp<mo[i].l) change(num[lp++],0);
77         while(lp>mo[i].l) change(num[--lp],1);
78         while(rp<mo[i].r) change(num[++rp],1);
79         while(rp>mo[i].r) change(num[rp--],0);
80         mo[i].ans=ask(mo[i].typ,mo[i].q);
81     }
82     sort(mo+1,mo+1+m,com);
83     for(i=1;i<=m;i++)
84         mo[i].ans?puts("hana"):puts("bi");
85     return 0;
86 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/9964045.html