zoukankan      html  css  js  c++  java
  • bzoj 5016 [Snoi2017]一个简单的询问

    题面

    https://www.lydsy.com/JudgeOnline/problem.php?id=5016

    题解

    莫队算法

    因此我们可以用(l,r) 表示ask(1,l,1,r) 然后就可以了莫队了

    用num1,num2两个数组记录下当前两个区间中每个数字分别出现多少次

    Code

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 
     5 ll read(){
     6     ll x=0,f=1;char c=getchar();
     7     while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
     8     while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
     9     return x*f;
    10 }
    11 
    12 const int maxn=50050;
    13 const int sz=250;
    14 int n;
    15 int a[maxn];
    16 int Q,tot;
    17 struct query{
    18     int l,r,id,ad;
    19     bool operator < (query ano) const{
    20         if(l/sz==ano.l/sz) return r<ano.r;
    21         else return l<ano.l;
    22     }
    23 } q[maxn*10];
    24 
    25 inline void add(int l,int r,int id,int ad){
    26     q[++tot].l=l,q[tot].r=r;
    27     q[tot].id=id,q[tot].ad=ad;
    28 }
    29 int num1[maxn],num2[maxn],ans[maxn];
    30 
    31 int main(){
    32 #ifdef LZT
    33     freopen("in","r",stdin);
    34 #endif
    35     n=read();
    36     for(int i=1;i<=n;i++) a[i]=read();
    37     Q=read();
    38     for(int i=1;i<=Q;i++){
    39         int l1,r1,l2,r2;
    40         l1=read(),r1=read(),l2=read(),r2=read();
    41         add(r1,r2,i,1);
    42         add(l1-1,r2,i,-1);
    43         add(r1,l2-1,i,-1);
    44         add(l1-1,l2-1,i,1);
    45     }
    46     sort(q+1,q+tot+1);
    47     int L=0,R=0,res=0;
    48     for(int i=1;i<=tot;i++){
    49         while(L<q[i].l){L++;res+=num2[a[L]];num1[a[L]]++;}
    50         while(L>q[i].l){res-=num2[a[L]];num1[a[L]]--;L--;}
    51         while(R<q[i].r){R++;res+=num1[a[R]];num2[a[R]]++;}
    52         while(R>q[i].r){res-=num1[a[R]];num2[a[R]]--;R--;}
    53         ans[q[i].id]+=res*q[i].ad;
    54     }
    55     for(int i=1;i<=Q;i++)
    56         printf("%d
    ",ans[i]);
    57     return 0;
    58 }
    59 
    60 /*
    61 5
    62 1 1 1 1 1
    63 2
    64 1 2 3 4
    65 1 1 4 4
    66 */
    View Code

    Review

    这样做的动机?

    (数据范围50000=>应该用$O(n sqrt n)$的做法=>莫队)

    (可离线的区间问题=>莫队)

    应该不算难想到

  • 相关阅读:
    索引!
    事件event
    Erlang运行时源码分析之——线程进度机制
    Erlang 运行时中使用的读写锁解析
    经典互斥算法解析
    网格布局之grid
    注册简单表单
    前端入门之自我介绍
    Python之一后置固件yield和终结函数addfinalizer
    python中yield 与 return 区别
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9372746.html
Copyright © 2011-2022 走看看