zoukankan      html  css  js  c++  java
  • 【洛谷 P3674】 小清新人渣的本愿(bitset,莫队)

    题目链接
    因为每个数都是(10^5)以内,考虑直接用(bitset)维护。
    (a-b=x),其实就是看是否有(p)(p+x)同时存在,直接(bitset)移位按位与一下就好了。
    (a+b=x),这个直接搞不好搞,所以考虑转化。

    [a-(N-b)=a+b-N=x-N ]

    其中(N)为一个常数,令(f(x)=N-x),则有

    [f(b)-f(x)=a ]

    于是再开个(bitset)维护(f(x)),然后就很显然了。
    (a*b=x),这个显然没法用(bitset)做,但是(x)的因数个数是(sqrt x)级别的,所以直接暴力枚举因数就行了。
    为了防止负数的出现,上文中的(N)取题中的值域上限(10^5)
    最后套上莫队模板。

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <bitset>
    #include <cmath>
    #include <iostream>
    using namespace std;
    const int MAXN = 100010;
    bitset <MAXN> p1, p2;
    int n, m, a[MAXN];
    inline int read(){
        int s = 0;
        char ch = getchar();
        while(ch < '0' || ch > '9') ch = getchar();
        while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); }
        return s;
    }
    int Q, v[MAXN], ans[MAXN];
    struct ask{
        int type, l, r, c, id;
        int operator < (const ask A) const{
            return l / Q == A.l / Q ? r < A.r : l < A.l;
        }
    }q[MAXN];
    void add(int x){
        ++v[a[x]];
        p1[a[x]] = p2[100000 - a[x]] = 1;
    }
    void del(int x){
        if(!--v[a[x]])
            p1[a[x]] = p2[100000 - a[x]] = 0;
    }
    int main(){
        n = read(); m = read(); Q = sqrt(n);
        for(int i = 1; i <= n; ++i)
            a[i] = read();
        for(int i = 1; i <= m; ++i)
            scanf("%d%d%d%d", &q[i].type, &q[i].l, &q[i].r, &q[i].c), q[i].id = i;
        sort(q + 1, q + m + 1);
        int l = 1, r = 0;
        for(int i = 1; i <= m; ++i){
            while(r < q[i].r) add(++r);
            while(l > q[i].l) add(--l);
            while(r > q[i].r) del(r--);
            while(l < q[i].l) del(l++);
            if(q[i].type == 1){
                ans[q[i].id] = (p1 & (p1 >> q[i].c)).any();
            }else if(q[i].type == 2){
                ans[q[i].id] = (p1 & (p2 >> (100000 - q[i].c))).any();
            }else{
                if(!q[i].c) ans[q[i].id] = v[0];
                int sqr = sqrt(q[i].c);
                for(int j = 1; j <= sqr; ++j)
                    if(q[i].c % j == 0)
                        if(v[j] && v[q[i].c / j]){
                            ans[q[i].id] = 1;
                            break;
                        }
            }
        }
        for(int i = 1; i <= m; ++i)
            printf("%s
    ", ans[i] ? "hana" : "bi");
        return 0;
    }
    
    
  • 相关阅读:
    兼容性测试中如何切换和管理多个JDK版本
    Win10的分辨率问题
    sql和access中截取字符串的区别
    ArcGIS制图之Sub Points点抽稀
    Office版本问题0x80029C4A
    ArcGIS制图之Maplex自动点抽稀
    ArcGIS制图之Subset工具点抽稀
    .NET破解之100%营销QQ辅助软件【更新】
    Office2016体验
    Log4net中的调错
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/11027048.html
Copyright © 2011-2022 走看看