莫队+bitset版子题
题面废话过多,引起不适。
对于一、二问,用bitset维护区间内每个数是否出现,错位与判断可行性。
第三问只需在之前基础上枚举约数即可(复杂度为根号n)
总复杂度O(n^1.5)
(我代码巨丑,想想完全不用分开写,我就是个傻子)
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<bitset> using namespace std; const int maxn = 200005; int n, m, num[maxn]; int ans[maxn], n1, n2, n3; struct ss { int l; int r; int x; int p; } a[maxn], a1[maxn], a2[maxn], a3[maxn]; bool cmp_r(ss a, ss b) { return a.r < b.r; } bool cmp_l(ss a, ss b) { return a.l < b.l; } int nl[maxn], nr[maxn], tnr[maxn], ss[maxn]; bitset <maxn> s; bitset <maxn> s2; bitset <maxn> st; int count1() { memset(nl, 0, sizeof(nl)); memset(nr, 0, sizeof(nr)); memset(tnr, 0, sizeof(tnr)); int i, j, q, ll, rr; int tn=0, sizek; sort(a+1, a+1+m, cmp_l); sizek=sqrt(n); for(i=1; i <= m; i++) tnr[a[i].l/sizek+1]=i; for(i=1; i <= n; i++) { if(tnr[i] != 0) tn++, nl[tn]=nr[tn-1]+1, nr[tn]=tnr[i]; } for(i=1; i <= tn; i++) { memset(ss, 0, sizeof(ss)); s.reset(); st.reset(); sort(a+nl[i], a+nr[i]+1, cmp_r); ll=a[nl[i]].l; rr=a[nl[i]].l-1; for(q=nl[i]; q <= nr[i]; q++) { for(j=rr+1; j <= a[q].r; j++) { s[num[j]]=1; ss[num[j]]++; } for(j=a[q].l; j <= ll-1; j++) { s[num[j]]=1; ss[num[j]]++; } for(j=ll; j <= a[q].l-1; j++) { ss[num[j]]--; if(!ss[num[j]]) s[num[j]]=0; } ll=a[q].l; rr=a[q].r; st=((s<<a[q].x) & (s)); if(st.any()) ans[a[q].p]=1; else ans[a[q].p]=0; } } return 0; } int count2() { memset(nl, 0, sizeof(nl)); memset(nr, 0, sizeof(nr)); memset(tnr, 0, sizeof(tnr)); int i, j, q, ta, ll, rr; int tn=0, sizek; sort(a+1, a+1+m, cmp_l); sizek=sqrt(n); for(i=1; i <= m; i++) tnr[a[i].l/sizek+1]=i; for(i=1; i <= n; i++) { if(tnr[i] != 0) tn++, nl[tn]=nr[tn-1]+1, nr[tn]=tnr[i]; } for(i=1; i <= tn; i++) { memset(ss, 0, sizeof(ss)); s.reset(); st.reset(); s2.reset(); sort(a+nl[i], a+nr[i]+1, cmp_r); ll=a[nl[i]].l; rr=a[nl[i]].l-1; for(q=nl[i]; q <= nr[i]; q++) { for(j=rr+1; j <= a[q].r; j++) { s[num[j]]=1; s2[100000-num[j]]=1; ss[num[j]]++; } for(j=a[q].l; j <= ll-1; j++) { s[num[j]]=1; s2[100000-num[j]]=1; ss[num[j]]++; } for(j=ll; j <= a[q].l-1; j++) { ss[num[j]]--; if(!ss[num[j]]) s[num[j]]=0, s2[100000-num[j]]=0; } ll=a[q].l; rr=a[q].r; st=((s<<(100000-a[q].x)) & (s2)); if(st.any()) ans[a[q].p]=1; else ans[a[q].p]=0; } } return 0; } int count3() { memset(nl, 0, sizeof(nl)); memset(nr, 0, sizeof(nr)); memset(tnr, 0, sizeof(tnr)); int i, j, q, ta, ll, rr, y; int tn=0, sizek; sort(a+1, a+1+m, cmp_l); sizek=sqrt(n); for(i=1; i <= m; i++) tnr[a[i].l/sizek+1]=i; for(i=1; i <= n; i++) { if(tnr[i] != 0) tn++, nl[tn]=nr[tn-1]+1, nr[tn]=tnr[i]; } for(i=1; i <= tn; i++) { memset(ss, 0, sizeof(ss)); s.reset(); sort(a+nl[i], a+nr[i]+1, cmp_r); ll=a[nl[i]].l; rr=a[nl[i]].l-1; for(q=nl[i]; q <= nr[i]; q++) { for(j=rr+1; j <= a[q].r; j++) { s[num[j]]=1; ss[num[j]]++; } for(j=a[q].l; j <= ll-1; j++) { s[num[j]]=1; ss[num[j]]++; } for(j=ll; j <= a[q].l-1; j++) { ss[num[j]]--; if(!ss[num[j]]) s[num[j]]=0; } ll=a[q].l; rr=a[q].r; ans[a[q].p]=0; for(y=1; y <= sqrt(a[q].x); y++) { if(a[q].x%y == 0 && s[y] && s[a[q].x/y]) ans[a[q].p]=1; } } } return 0; } int main() { ios::sync_with_stdio(false); int i, tm, ta; cin>>n>>m; for(i=1; i <= n; i++) cin>>num[i]; for(i=1; i <= m; i++) { cin>>ta; if(ta == 1) n1++, cin>>a1[n1].l>>a1[n1].r>>a1[n1].x, a1[n1].p=i; if(ta == 2) n2++, cin>>a2[n2].l>>a2[n2].r>>a2[n2].x, a2[n2].p=i; if(ta == 3) n3++, cin>>a3[n3].l>>a3[n3].r>>a3[n3].x, a3[n3].p=i; } tm=m; m=n1; for(i=1; i <= m; i++) a[i]=a1[i]; count1(); m=n2; for(i=1; i <= m; i++) a[i]=a2[i]; count2(); m=n3; for(i=1; i <= m; i++) a[i]=a3[i]; count3(); for(i=1; i <= tm; i++) if(ans[i]) cout<<"hana"<<endl; else cout<<"bi"<<endl; return 0; }