[BZOJ4810][YNOI2017]由乃的玉米田(莫队+bitset)

莫队,cnt数组记录每个数的个数,bitset b1[i]记录数i是否出现过,b2[i]记录数M-i是否出现过。

减法:((b1>>x)&b1).any()。

加法:(((b2>>(M-x))&b1).any()。

乘法:若存在一定有一个数<=sqrt(1e5),枚举即可。

复杂度:$O(n\sqrt{n}(\frac{A}{\omega}+\sqrt{A}))$ 无法理解这个复杂度为什么能过。

 1 #include<cstdio>
 2 #include<bitset>
 3 #include<algorithm>
 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 5 using namespace std;
 6 
 7 const int N=100010,M=100000,B=320;
 8 bool ans[N];
 9 int n,m,tot,a[N],bel[N],cnt[N];
10 bitset<M>b1,b2;
11 struct Q{ int op,l,r,x,id; }q[N];
12 bool operator <(const Q &a,const Q &b){ return bel[a.l]==bel[b.l] ? a.r<b.r : bel[a.l]<bel[b.l]; }
13 
14 void add(int x){ cnt[x]++; b1[x]=b2[M-x]=1; }
15 void del(int x){ cnt[x]--; if (!cnt[x]) b1[x]=b2[M-x]=0; }
16 
17 int main(){
18     freopen("bzoj4810.in","r",stdin);
19     freopen("bzoj4810.out","w",stdout);
20     scanf("%d%d",&n,&m); tot=(n-1)/B+1;
21     rep(i,1,n) scanf("%d",&a[i]),bel[i]=(i-1)/B+1;
22     rep(i,1,m) scanf("%d%d%d%d",&q[i].op,&q[i].l,&q[i].r,&q[i].x),q[i].id=i;
23     sort(q+1,q+m+1);
24     int L=1,R=0;
25     rep(i,1,m){
26         int op=q[i].op,l=q[i].l,r=q[i].r,x=q[i].x;
27         while (R<r) add(a[++R]);
28         while (R>r) del(a[R--]);
29         while (L>l) add(a[--L]);
30         while (L<l) del(a[L++]);
31         if (op==1) ans[q[i].id]=((b1>>x)&b1).any();
32         if (op==2) ans[q[i].id]=((b2>>(M-x))&b1).any();
33         if (op==3){
34             bool fl=0;
35             rep(j,1,min(500,x)) if (b1[j] && b1[x/j] && x%j==0) { fl=1; break; }
36             ans[q[i].id]=fl;
37         }
38     }
39     rep(i,1,m) puts(ans[i] ? "yuno" : "yumi");
40     return 0;
41 }

 

posted @ 2018-12-15 13:16  HocRiser  阅读(154)  评论(0编辑  收藏  举报