• Luogu3674小清新人渣的本愿


    https://zybuluo.com/ysner/note/1109536

    题面

    给你一个序列a,长度为n,有m次操作,每次询问一个区间

    • 是否可以选出两个数它们的差为x

    • 是否可以选出两个数它们的和为x

    • 是否可以选出两个数它们的乘积为x 。
      选出的这两个数可以是同一个位置的数

    • 对于100%的数据,n,m,c <= 100000

    知识迁移

    (bitset)的原理是将一大堆值为(0/1)的数压成一个数。
    通过(i>>x)等操作,我们可以快速访问(i)数组右移(x)位后的状态(即只剩右数(n-x)个值。
    (bitset)数组可以当作一个数来看待并进行>>,<<,&,^等操作(详见高斯消元总结)。
    还有一些(STL)函数。

    • b.any():b中是否存在置为1的二进制位?
    • b.none():b中不存在置为1的二进制位吗?
    • b.count():b中置为1的二进制位的个数
    • b.size():b中二进制位的个数
    • b[pos]:访问b中在pos处的二进制位
    • b.test(pos):b中在pos处的二进制位是否为1?
    • b.set():把b中所有二进制位都置为1
    • b.set(pos):把b中在pos处的二进制位置为1
    • b.reset():把b中所有二进制位都置为0
    • b.reset(pos):把b中在pos处的二进制位置为0
    • b.flip():把b中所有二进制位逐位取反
    • b.flip(pos):把b中在pos处的二进制位取反

    解析

    这题显然只能用莫队搞啊。
    操作三枚枚因数就成,(O(msqrt{n}))稳稳的。
    操作一二好像会到(O(n^2))?很耸?
    发现我们询问时只要问存在性,即只有(0/1)两种状态,于是可以(bitset)优化一波,(O(frac{n^2}{64}))强行卡过此题。

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<bitset>
    #define ll long long
    #define re register
    #define il inline
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=1e5+10000;
    bitset<N>S1,S2;
    bool ans[N];
    int n,m,blk,num[N],a[N];
    struct Que
    {
      int id,op,l,r,x,bl;
      bool operator < (const Que &o){return (bl<o.bl)||(bl==o.bl&&r<o.r);}
    }q[N];
    il int gi()
    {
      re int x=0,t=1;
      re char ch=getchar();
      while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il void add(re int x){if(!num[x]++) S1[x]=S2[100000-x]=1;}
    il void del(re int x){if(!--num[x]) S1[x]=S2[100000-x]=0;}
    int main()
    {
      n=gi();m=gi();blk=sqrt(n);
      fp(i,1,n) a[i]=gi();
      fp(i,1,m)
        {
          re int op=gi(),l=gi(),r=gi(),x=gi();
          q[i]=(Que){i,op,l,r,x,l/blk};
        }
      sort(q+1,q+1+m);
      re int L=1,R=0;
      fp(i,1,m)
        {
          while(L>q[i].l) add(a[--L]);
          while(R<q[i].r) add(a[++R]);
          while(L<q[i].l) del(a[L++]);
          while(R>q[i].r) del(a[R--]);
          if(q[i].op==1) ans[q[i].id]=(S1&(S1>>q[i].x)).any();
          if(q[i].op==2) ans[q[i].id]=(S1&(S2>>(100000-q[i].x))).any();
          if(q[i].op==3)
        fp(k,1,sqrt(q[i].x))
          if(q[i].x%k==0)
            if(S1[k]&S1[q[i].x/k]) {ans[q[i].id]=1;break;}
        }
      fp(i,1,m) ans[i]?puts("hana"):puts("bi");
      return 0;
    }
    
  • 相关阅读:
    javascript 实现 TreeView全选(实现子节点全选,中父节点自动全选)
    关于健康档案的基本架构与数据标准
    SQLite内建语法表
    狼群中的男人(A Man Among Wolves)
    教你瞬间赢得别人信任的 “冷读术”
    SymbianOS精要
    为幼龄儿童设计 iPad 软件介面的四条心得
    OpenGL ES
    如何变得更加优秀
    创业的八大能力
  • 原文地址:https://www.cnblogs.com/yanshannan/p/8807819.html
Copyright © 2020-2023  润新知