• 洛谷 P3674 小清新人渣的本愿


    题目链接

    求给定区间内有无两个数的和/差/积为给定的数(两个数可相同)。

    首先操作可离线,范围又只有(10^5),还是区间问题,又没有什么数据结构维护,那大概就是莫队吧。

    我们维护每种数出现次数,记为(sum_i)

    然后开两个bitset当作bool 数组用,分别统计(i)(100000 - i)的值是否存在。

    求差:

    [a - b = x \ a = b + x\ ]

    ans = (bitset1 & (bitset1 << x)).any();
    

    求和:

    [a + b = x \ a + (100000 - x)= (100000 - b) \ ]

    ans = (bitset2 & (bitset1 << (100000 - x))).any();
    

    求积:
    直接对(x)分解因数,枚举所有(leq sqrt(x))的因数,然后判断(i)(frac{i}{x})是否存在与bitset1中

    
    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 100050;
    
    int n,m;
    int a[N];
    
    struct OP{
        int opt,l,r,v,id;
    }q[N];
    int belong[N],block;
    bool cmp(OP a,OP b){
        return (belong[a.l] ^ belong[b.l]) ? (belong[a.l] < belong[b.l]) : ( (belong[a.l] & 1) ? a.r < b.r : a.r > b.r );
    }
    
    bitset<N> mp1,mp2;//mp1[i] = mp2[100000 - i] 表示i有没有
    int sum[N];
    
    int ans[N];
    
    void add(int x){
        ++ sum[a[x]];
        if(sum[a[x]] == 1) mp1[a[x]] = mp2[100000 - a[x]] = 1;
    }
    void del(int x){
        -- sum[a[x]];
        if(sum[a[x]] == 0) mp1[a[x]] = mp2[100000 - a[x]] = 0;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; ++ i) scanf("%d",&a[i]);
        
        for(int i = 1; i <= m; ++ i){
            scanf("%d%d%d%d",&q[i].opt,&q[i].l,&q[i].r,&q[i].v);
            q[i].id = i;
        }
        
        block = ceil(sqrt(n));
        for(int i = 1; i <= n; ++ i) belong[i] = (i - 1) / block + 1;
        sort(q + 1, q + m + 1, cmp);
        
        int L = 1, R = 0;
        for(int i = 1; i <= m; ++ i){
            while(L < q[i].l) del(L ++);
            while(L > q[i].l) add(-- L);
            while(R < q[i].r) add(++ R);
            while(R > q[i].r) del(R --);
            
            if(q[i].opt == 1){//a - b = v -> a = b + v
                ans[q[i].id] = (mp1 & (mp1 << q[i].v)).any();
            }
            if(q[i].opt == 2){//a + b = v -> a = v - b -> a = (100000 - b) - (100000 - v) 
                ans[q[i].id] = (mp1 & (mp2 >> (100000 - q[i].v)) ).any();
            }
            if(q[i].opt == 3){
                for(int j = 1; 1ll * j * j <= q[i].v; ++ j){
                    if(q[i].v % j) continue;
                    
                    int x = j, y = q[i].v / j;
                    ans[q[i].id] = mp1[x] & mp1[y];
                    if(ans[q[i].id]) break;
                }
            }
            /*if(a[i].opt == 4){
                
            }*/
        }
        
        for(int i = 1; i <= m; ++ i) 
        puts(ans[i] ? "hana" : "bi" );
        
        return 0;
    }
    
    
  • 相关阅读:
    linux redis安装 5.0.2
    Linux nginx安装步骤 centos7
    fastjson JSONObject.toJSONString 出现 $ref: "$."的解决办法(重复引用)
    docker redis安装及配置(外网访问 关闭安全限制 设置密码)
    JDK dump
    mysql8 修改root密码
    docker系列详解<二>之常用命令
    获取地理位置
    js调用摄像头
    点击时扩散效果
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/13386005.html
Copyright © 2020-2023  润新知