zoukankan      html  css  js  c++  java
  • [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业

    [bzoj3809]Gty的二逼妹子序列/[bzoj3236][Ahoi2013]作业

    bzoj   bzoj

    题目大意:一个序列,m个询问在$[l,r]$区间的$[x,y]$范围内的数的个数/种类。

    思路:

    因为看不出来怎么做,所以考虑莫队。

    太懒想写个树状数组但是$nsqrt{n}log_{n}$太虚

    所以将数分块,修改$O(1)$,查询$O(sqrt{n})$

    完结

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 using namespace std;
      5 const int N=114514,SN=366;
      6 template<typename tp>inline void read(tp &kk){
      7     tp ret=0,f=1;char ch=getchar();
      8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
      9     while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
     10     kk=ret*f;
     11 }
     12 int n,m,a[N],bl[N],bs;
     13 struct ques
     14 {
     15     int l,r,x,y,id;
     16     bool operator < (const ques &a)const{return bl[l]==bl[a.l]?r<a.r:bl[l]<bl[a.l];}
     17     void init(int i){id=i;read(l),read(r),read(x),read(y);}
     18 }q[N];
     19 
     20 struct ans
     21 {
     22     int a1,a2;
     23     ans(){a1=a2=0;}
     24 }prt[N];
     25 
     26 struct ShangYang
     27 {
     28     int l[SN],r[SN],buk[SN],bukk[SN],b[N],po[N],sz;
     29     void start()
     30     {
     31         sz=ceil(sqrt(100000));
     32         int bb=0;
     33         for(int i=1;i<=n;i+=sz)
     34         {
     35             bb++;
     36             l[bb]=i;
     37             r[bb]=min(i+sz-1,n);
     38             for(int j=l[bb];j<=r[bb];j++) b[j]=bb;
     39         }
     40     }
     41     void add(int x)
     42     {
     43         if(!po[x]) bukk[b[x]]++;
     44         po[x]++;
     45         buk[b[x]]++;
     46     }
     47     void mus(int x)
     48     {
     49         po[x]--;
     50         buk[b[x]]--;
     51         if(!po[x]) bukk[b[x]]--;
     52     }
     53     ans query(int x,int y)
     54     {
     55         ans ret;
     56         int bx=b[x],by=b[y];
     57         if(bx==by)
     58         {
     59             for(int i=x;i<=y;i++)
     60                 ret.a1+=po[i],ret.a2+=(!!po[i]);
     61         }else
     62         {
     63             for(int i=bx+1;i<by;i++)
     64                 ret.a1+=buk[i],ret.a2+=bukk[i];
     65             for(int i=x;i<=r[bx];i++)
     66                 ret.a1+=po[i],ret.a2+=(!!po[i]);
     67             for(int i=l[by];i<=y;i++)
     68                 ret.a1+=po[i],ret.a2+=(!!po[i]);
     69         }
     70         return ret;
     71     }
     72 }sy;
     73 
     74 void icu()
     75 {
     76     int l=1,r=0;
     77     for(int i=1;i<=m;i++)
     78     {
     79         while(r<q[i].r) sy.add(a[++r]);
     80         while(l>q[i].l) sy.add(a[--l]);
     81         while(r>q[i].r) sy.mus(a[r--]);
     82         while(l<q[i].l) sy.mus(a[l++]);
     83         prt[q[i].id]=sy.query(q[i].x,q[i].y);
     84     }
     85 }
     86 
     87 int main()
     88 {
     89     read(n),read(m);
     90     bs=ceil(sqrt(n));
     91     for(int i=1;i<=n;i++) read(a[i]),bl[i]=(i-1)/bs+1;
     92     for(int i=1;i<=m;i++) q[i].init(i);
     93     // puts("114514");
     94     sy.start();
     95     sort(q+1,q+1+m);
     96     icu();
     97     // puts("1919810");
     98     for(int i=1;i<=m;i++) printf("%d %d
    ",prt[i].a1,prt[i].a2);
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    封装

    如何通过命令行窗口查看sqlite数据库文件
    标签控件
    信息提示框
    循环
    数组
    switch
    成员局部变量
    变量
  • 原文地址:https://www.cnblogs.com/rikurika/p/11252219.html
Copyright © 2011-2022 走看看