资讯详情

Problem - 220B - Codeforces(莫队)

Problem - 220B - Codeforces

题目大意:给定长度为n的数组,m次查询,求每次查询的区间中, a i a_i ai= n u m [ a i ] num[a_i] num[ai]的个数.

解题思路:n的范围是1e5.基本确定这是莫队的问题. 莫队通过将长度作为离线问题来处理离线问题 n n n数组分块成 n \sqrt{n} n 块进行处理,处理前进行排序,对于起点,用块决定顺序,对于相同块,用n决定顺序. 复杂性的证明:对于右指针的每一块,它必须单调地移动,所以复杂性是 O ( n ) O(n) O(n),总共有 n \sqrt{n} n ​块,所以右指针的复杂度为 O ( n n ) O(n\sqrt{n}) O(nn ​),对于左指针,在同一块内的移动次数最多是 n \sqrt{n} n ​,而总共有m次询问,那么左指针的复杂度就是 O ( m n ) O(m\sqrt{n}) O(mn ​).合起来的复杂度就是近似于 O ( n n ) O(n\sqrt{n}) O(nn ​).

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define syncfalse ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
const int N = 1e5+5;
int BLOCK, n, m, answer;
int a[N], cnt[N];
struct node{ 
        
    int l, r, id, ans;
}b[N];

bool cmp1(const node&a, const node&b){ 
        
    if (a.l/BLOCK==b.l/BLOCK){ 
        
        return a.r < b.r;
    }
    return a.l/BLOCK < b.l/BLOCK;
}

bool cmp2(const node&a, const node&b){ 
        
    return a.id < b.id;
}

void add(int position){ 
        
    if (a[position]>n)return;
    cnt[a[position]]++;
    if (cnt[a[position]]==a[position]){ 
        
        answer++;
    }else if (cnt[a[position]]==a[position]+1){ 
        
        answer--;
    }
}

void remove(int position){ 
        
    if (a[position]>n)return;
    cnt[a[position]]--;
    if (cnt[a[position]]==a[position])answer++;
    else if (cnt[a[position]]==a[position]-1)answer--;
}

int main(){ 
        
    syncfalse
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    cin>>n>>m;
    BLOCK=sqrt(n);
    for (int i = 1; i <= n; ++i)cin>>a[i];
    for (int i = 1; i <= m; ++i){ 
        cin>>b[i].l>>b[i].r;b[i].id=i;}
    sort(b+1, b+1+m, cmp1);
    int nl=0, nr=1;
    for (int i = 1; i <= m; ++i){ 
        
        int l = b[i].l, r = b[i].r;
        while(nl+1<l){ 
        
            remove(nl+1);
            nl++;
        }
        while(nl>=l){ 
        
            add(nl);
            nl--;
        }
        while(nr<=r){ 
        
            add(nr);
            nr++;
        }
        while(nr>r+1){ 
        
            remove(nr-1);
            nr--;
        }
        b[i].ans=answer;
    }
    sort(b+1,b+1+m, cmp2);
    for (int i = 1; i <= m; ++i){ 
        
        cout << b[i].ans << "\n";
    }

    return 0;
}

标签: 二极管db220b

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台