题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4810
思路还是比较显然,第一反应应该就是莫队。
考虑怎么维护三个询问,想到了要维护每一个数字是否出现就想到了要用bitset。那么这道题就做完了。
莫队相当于是在利用bitset维护一个01序列$f$,表示每一个数字是否出现在这一段区间。
1.如果差为$x$,将这个$f$左移$x$然后判断是否和原来的$f$集合有交集即可。
2.如果和为$x$,将这个$f$翻转并左移$100000-x$然后判断是否和原来的$f$集合有交集即可。
3.如果积为$x$,直接${O(sqrt{x})}$的枚举判断即可。
复杂度${O(nsqrt{n}+frac{n^{2}}{64})}$
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstring> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #include<bitset> 11 using namespace std; 12 #define llg int 13 #define maxn 100010 14 #define MA 100000 15 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout); 16 17 inline llg getint() 18 { 19 llg w=0,q=0; char c=getchar(); 20 while((c<'0' || c>'9') && c!='-') c=getchar(); 21 if (c=='-') q=1, c=getchar(); while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 22 return q ? -w : w; 23 } 24 25 bitset<MA+1>f,g; 26 llg ans[maxn],n,m,a[maxn],KUAI,cnt[maxn]; 27 28 struct node {llg ty,l,r,x,num;}ask[maxn]; 29 30 bool cmp(const node&a,const node&b) 31 { 32 if (a.l/KUAI==b.l/KUAI) return a.r<b.r; 33 else return a.l/KUAI<b.l/KUAI; 34 } 35 36 void init() 37 { 38 cin>>n>>m; 39 KUAI=sqrt(n); 40 for (llg i=1;i<=n;i++) a[i]=getint(); 41 for (llg i=1;i<=m;i++) 42 ask[i].ty=getint(),ask[i].l=getint(),ask[i].r=getint(),ask[i].x=getint(),ask[i].num=i; 43 sort(ask+1,ask+m+1,cmp); 44 } 45 46 int main() 47 { 48 yyj("mo"); 49 init(); 50 llg l=0,r=0; 51 for (llg i=1;i<=m;i++) 52 { 53 while (l>ask[i].l) l--,cnt[a[l]]++,f[a[l]]=1,g[MA-a[l]]=1; 54 while (r<ask[i].r) r++,cnt[a[r]]++,f[a[r]]=1,g[MA-a[r]]=1; 55 while (l<ask[i].l) {cnt[a[l]]--; if (!cnt[a[l]]) f[a[l]]=0,g[MA-a[l]]=0; l++;} 56 while (r>ask[i].r) {cnt[a[r]]--; if (!cnt[a[r]]) f[a[r]]=0,g[MA-a[r]]=0; r--;} 57 58 if (ask[i].ty==1) 59 { 60 if (((f>>ask[i].x)&f).any()) ans[ask[i].num]=1; else ans[ask[i].num]=0; 61 62 } 63 64 if (ask[i].ty==2) 65 { 66 if (((g>>(MA-ask[i].x))&f).any()) ans[ask[i].num]=1; else ans[ask[i].num]=0; 67 } 68 69 if (ask[i].ty==3) 70 { 71 for (llg k=1;k*k<=ask[i].x;k++) 72 if (ask[i].x%k==0) 73 { 74 if (f[k] && f[ask[i].x/k]) {ans[ask[i].num]=1; break;} 75 } 76 } 77 if (ask[i].x==0 && f[0]) ans[ask[i].num]=1; 78 } 79 for (llg i=1;i<=m;i++) puts(ans[i]?"yuno":"yumi"); 80 return 0; 81 }