BZOJ --- 4810: [Ynoi2017] is the corn field by the team [Mo] + bitset

Questions surface:

BZOJ --- 4810

Meaning of the questions:

Given a sequence, each time a query interval three cases: (1) whether there is a difference between the two numbers X (2) whether there are two numbers X (3) whether there is a product of two numbers is X

analysis:

Mo is easy to think of the team offline, consider how to maintain answer; for ① Operation: A - B = X ----> A = B + X, are a collection for plus X, with bitset maintenance interval numbers set S only need to determine S & (S << X) can be, for ②: a + B = X ----> a = -B + X, but not maintain bitset negative, then simply the maintenance (NB) set T, then there are: A - (NB) = X - N ---> A + (NX) = (NB), just determined (S << (NX)) & T to; for three operations, i.e., direct violence factoring Analyzing can

Code:

#include <bits/stdc++.h>
 
using namespace std;
const int maxn = 1e5+15;
struct node{
    int op,l,r,x,pos;
}p[maxn];
int n,m,block,a[maxn],num[maxn],ans[maxn];
bool cmp(node a,node b){
    return a.l/block==b.l/block?a.r<b.r:a.l<b.l;
}
bitset<maxn> bs1,bs2,s;
inline void add(int x){
    bs1[a[x]] = 1;
    bs2[maxn-1-a[x]] = 1;
    num[a[x]]++;
}
inline void del(int x){
    if(--num[a[x]]==0){
        bs1[a[x]] = 0;
        bs2[maxn-1-a[x]] = 0;
    }
}
int main(){
    cin >> n >> m;
    block = sqrt(n*1.0);
    for(int i = 1;i <= n; ++i) cin >> a[i];
    for(int i = 0;i < m; ++i) cin>>p[i].op>>p[i].l>>p[i].r>>p[i].x,p[i].pos=i;
    sort(p,p+m,cmp);
    int L = 1,R = 0;
    for(int i = 0;i < m; ++i){
         while(R < p[i].r) ++R,add(R);
         while(R > p[i].r) del(R),--R;
         while(L < p[i].l) del(L),++L;
         while(L > p[i].l) --L,add(L);
         if(p[i].op == 1){
            s = (bs1<<p[i].x)&bs1;
            if(s.any()) ans[p[i].pos] = 1;
         }
         else if(p[i].op == 2){
            s = (bs1<<(maxn-1-p[i].x))&bs2;
            if(s.any()) ans[p[i].pos] = 1;
         }
         else{
            for(int j = 1;j*j<=p[i].x; ++j){
                if(p[i].x%j==0&&num[j]&&num[p[i].x/j]){
                   ans[p[i].pos] = 1;
                   break;
                }
            }
         }
    }
    for(int i = 0;i < m; ++i){
        if(ans[i]) puts("yuno");
        else puts("yumi");
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/qq_41157137/article/details/93376867