zoukankan      html  css  js  c++  java
  • Bzoj3236: [Ahoi2013]作业

    Bzoj3236: [Ahoi2013]作业

    刚学完莫队,不过这题用莫队的复杂度算起来好高啊,居然能过……

    像求逆序对一样用两个树状数组维护区间中每个数值出现的个数,以及每个数是否出现,前者用来求答案1,后者用来求答案2。

    在区间伸缩时加入删除最后更新答案即可。

    这次压行压的有点厉害,和DeepinC有的一拼了……

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 using namespace std;
     6 int L[1010],R[1010],pos[100010];
     7 struct ques
     8 {
     9     int L,R,a,b,id;
    10     #define L(x)  que[x].L
    11     #define R(x)  que[x].R
    12     #define a(x)  que[x].a
    13     #define b(x)  que[x].b
    14     #define id(x) que[x].id
    15     friend bool operator < (ques a,ques b)    
    16     {
    17         return (pos[a.L]^pos[b.L])?(pos[a.L]<pos[b.L]):((pos[a.L]&1)?(a.R<b.R):(a.R>b.R));
    18     }
    19 }que[1000010];
    20 int C[100010],C2[100010],cnt[100010];
    21 int n,m,a[100010];
    22 int eans1[1000010],eans2[1000010];
    23 #define lowbit(x) ((x)&(-(x)))
    24 inline int read()
    25 {
    26     int s=0;char a=getchar();
    27     while(a<'0'||a>'9')a=getchar();
    28     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
    29     return s;
    30 }
    31 void add(int x,int y)
    32 {while(x<=100010){C[x]+=y;x+=lowbit(x);}}
    33 int ask(int x)
    34 {int ans=0;while(x){ans+=C[x];x-=lowbit(x);}return ans;}
    35 void add2(int x,int y)
    36 {while(x<=100010){C2[x]+=y;x+=lowbit(x);}}
    37 int ask2(int x)
    38 {int ans=0;while(x){ans+=C2[x];x-=lowbit(x);}return ans;}
    39 signed main()
    40 {
    41     cin>>n>>m;
    42     for(int i=1;i<=n;i++)a[i]=read();
    43     for(int i=1;i<=m;i++)
    44     L(i)=read(),R(i)=read(),a(i)=read(),b(i)=read(),id(i)=i;
    45     int t=sqrt(n);    
    46     for(int i=1;i<=t;i++)
    47         L[i]=R[i-1]+1,R[i]=i*t;
    48     if(R[t]<n)t++,L[t]=R[t-1]+1;R[t]=n;
    49     for(int i=1;i<=t;i++)
    50     for(int j=L[i];j<=R[i];j++)
    51         pos[j]=i;
    52     sort(que+1,que+m+1);
    53     int l=1,r=0,ans1=0,ans2=0;
    54     for(int i=1;i<=m;i++)
    55     {
    56         ans1=ask(b(i))-ask(a(i)-1);
    57         while(l>L(i)){l--,add(a[l],1),ans1=ask(b(i))-ask(a(i)-1);if(cnt[a[l]]==0)add2(a[l],1);cnt[a[l]]++;  }
    58         while(l<L(i)){add(a[l],-1),ans1=ask(b(i))-ask(a(i)-1);if(cnt[a[l]]==1)add2(a[l],-1);cnt[a[l]]--,l++;}
    59         while(r<R(i)){r++,add(a[r],1),ans1=ask(b(i))-ask(a(i)-1);if(cnt[a[r]]==0)add2(a[r],1);cnt[a[r]]++;  }
    60         while(r>R(i)){add(a[r],-1),ans1=ask(b(i))-ask(a(i)-1);if(cnt[a[r]]==1)add2(a[r],-1);cnt[a[r]]--,r--;}
    61         ans2=ask2(b(i))-ask2(a(i)-1);
    62         eans1[id(i)]=ans1,eans2[id(i)]=ans2;
    63     }
    64     for(int i=1;i<=m;i++)
    65         printf("%d %d
    ",eans1[i],eans2[i]);
    66 }
    完整代码
  • 相关阅读:
    [线段树][数学]JZOJ 4237 Melancholy
    [规律]JZOJ 4222 恐怖的奴隶主
    [Tarjan][基环树]JZOJ 4221 互相追逐的点
    [斯特林数][自然数幂和]JZOJ 4220 WYF的盒子
    奇妙的骚操作
    [树形DP][概率期望]JZOJ 4225 宝藏
    操作系统基础知识
    计算机硬件知识整理
    ORM的查询
    ORM的记录添加和删除
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11240200.html
Copyright © 2011-2022 走看看