zoukankan      html  css  js  c++  java
  • BZOJ4810: [Ynoi2017]由乃的玉米田

    【传送门:BZOJ4810


    简要题意:

      给出n个数,给出m种询问:

      1 l r x判断是否在区间l到r中能选出两个数的差为x

      2 l r x判断是否在区间l到r中能选出两个数的和为x

      3 l r x判断是否在区间l到r中能选出两个数的乘积为x

      其中选出的两个数可以相等


    题解:

      肯定得离线

      用莫队吧(离线,第一时间就想到莫队)

      第三个询问可以暴力求因子搞一搞

      结果发现不会搞1和2

      上网搜了搜,学了一波bitset

      bitset简单来说可以当作一个二进制位来用,但是它并不需要二进制那样的庞大数据范围

      而且赋值只需要像数组一样赋值

      然后对于第1个操作,将当前bitset与当前的bitset向右移x位之后的bitset做一下and运算,假如有1,则说明成立

      然后对于第2个操作,将用第二个bitset作为第一个bitset的取反,然后用反转bitset右移后和正bitset做一下and运算,如果有1,则说明成立(这个东西,自己脑补,也挺容易理解的)


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<bitset>
    using namespace std;
    bitset<110000> bs1,bs2;
    int a[110000];
    int belong[110000];
    struct node
    {
        int opt,l,r,x,d,id;
    }q[1100000];int n,m;
    bool cmp1(node n1,node n2)
    {
        if(belong[n1.l]<belong[n2.l]) return true;
        if(belong[n1.l]>belong[n2.l]) return false;
        if(belong[n1.l]==belong[n2.l])
        {
            if(n1.r<n2.r) return true;
            if(n1.r>n2.r) return false;
        }
        return false;
    }
    bool cmp2(node n1,node n2)
    {
        return n1.id<n2.id;
    }
    int sum[110000];
    void add(int x)
    {
        sum[x]++;
        if(sum[x]==1) bs1[x]=1,bs2[n-x+1]=1;
    }
    void del(int x)
    {
        sum[x]--;
        if(sum[x]==0) bs1[x]=0,bs2[n-x+1]=0;
    }
    int solve1(int x)
    {
        if(((bs1)&(bs1>>x)).any()==true) return 1;
        else return 0;
    }
    int solve2(int x)
    {
        if(((bs1)&(bs2>>(n-x+1))).any()==true) return 1;
        else return 0;
    }
    int solve3(int x)
    {
        int t=int(sqrt(x+1));
        for(int i=1;i<=t;i++) if(x%i==0&&bs1[i]==1&&bs1[x/i]==1) return 1;
        return 0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int block=int(sqrt(n));
        for(int i=1;i<=n;i++)
        {
            int t=(i-1)/block+1;
            belong[i]=t;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&q[i].opt,&q[i].l,&q[i].r,&q[i].x);
            q[i].id=i;
        }
        sort(q+1,q+m+1,cmp1);
        int l=1,r=0;
        memset(sum,0,sizeof(sum));
        bs1.reset();bs2.reset();
        for(int i=1;i<=m;i++)
        {
            while(l>q[i].l){l--;add(a[l]);}
            while(l<q[i].l){del(a[l]);l++;}
            while(r>q[i].r){del(a[r]);r--;}
            while(r<q[i].r){r++;add(a[r]);}
            if(q[i].opt==1) q[i].d=solve1(q[i].x);
            if(q[i].opt==2) q[i].d=solve2(q[i].x);
            if(q[i].opt==3) q[i].d=solve3(q[i].x);
        }
        sort(q+1,q+m+1,cmp2);
        for(int i=1;i<=m;i++) if(q[i].d==1) printf("yuno
    "); else printf("yumi
    ");
        return 0;
    }

     

  • 相关阅读:
    多线程与MySQL(十)
    多进程与多线程(九)
    异常处理与网络编程(八)
    面向对象,绑定方法与异常处理(七)
    模块与对象(六)
    包与模块(五)
    迭代器与函数Python学习(四)
    函数与装饰器Python学习(三)
    数据库
    并发编程
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8551984.html
Copyright © 2011-2022 走看看