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

莫队+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;
}

猜你喜欢

转载自www.cnblogs.com/crraphael/p/11352574.html