洛谷 P3674 小清新人渣的本愿 [莫队 bitset]

传送门

题意:

给你一个序列a,长度为n,有Q次操作,每次询问一个区间是否可以选出两个数它们的差为x,或者询问一个区间是否可以选出两个数它们的和为x,或者询问一个区间是否可以选出两个数它们的乘积为x ,这三个操作分别为操作1,2,3


 

题面太强啦!!!

感觉就是莫队,想了一下分块不好搞更坚定了莫队的信念

$a-b=x$,$a=x+b$,放在权值数组上就是b右移x位,$bitset$大法好

加法同理

乘法,总共就$\sqrt{N}$个约数....

感觉复杂度$O(\frac{N^2}{64} + N\sqrt{N})$不靠谱结果竟然A了...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
using namespace std;
typedef long long ll;
const int N=1e5+5, M=2e5+5;
inline ll read(){
    char c=getchar();ll x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

int n, Q, a[N], op, l, r, x;

int block, m, pos[N];
struct meow{
    int l, r, x, type, qid;
    bool operator <(const meow &a) const {return pos[l]==pos[a.l] ? r<a.r : pos[l]<pos[a.l];}
}q[N];
int ans[N];

struct Meow{
    bitset<M> a, b, c;
    int cou[N];
    inline void add(int v) {
        cou[v]++;
        if(cou[v]==1) a[v]=1, b[v+N]=1, c[-v+N]=1;
    }
    inline void del(int v) {
        cou[v]--;
        if(cou[v]==0) a[v]=0, b[v+N]=0, c[-v+N]=0;
    }

    int Que(int type, int x) { //printf("Que %d %d\n",type,x);
        int ans=0;
        if(type==1) {
            if( (a & (a<<x)).any() ) ans=1;
        }else if(type==2) {
            if( (b & (c<<x)).any() ) ans=1;
        }else {
            int m=sqrt(x);
            for(int i=1; i<=m; i++) if(x%i == 0) 
                if(cou[i] && cou[x/i]) {ans=1; break;}
        }
        return ans;
    }
}A;
void modui(){
    int l=1, r=0;
    for(int i=1; i<=Q; i++){
        while(r<q[i].r) r++, A.add(a[r]);
        while(r>q[i].r) A.del(a[r]), r--;
        while(l<q[i].l) A.del(a[l]), l++;
        while(l>q[i].l) l--, A.add(a[l]);

        ans[q[i].qid]= A.Que(q[i].type, q[i].x);
    }
}
int main(){
//    freopen("in","r",stdin);
    n=read(); Q=read();
    block=sqrt(n); m=(n-1)/block+1;
    for(int i=1; i<=n; i++) a[i]=read(), pos[i]=(i-1)/block+1;
    for(int i=1; i<=Q; i++) 
        op=read(), l=read(), r=read(), x=read(), q[i]=(meow){l, r, x, op, i};
    sort(q+1, q+1+Q);
    modui();
    for(int i=1; i<=Q; i++) puts(ans[i] ? "hana" : "bi");
}

 

posted @ 2017-03-19 22:31  Candy?  阅读(375)  评论(0编辑  收藏  举报