[HEOI 2012] 采花

[题目链接]

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

[算法]

        首先预处理nxt[]数组 , 其中 , nxt[i]表示下一个和i号位颜色相同的位置 , 然后离线 , 将询问按左端点排序 , 每次将nxt[i]减一 , nxt[nxt[i]]加一

        用树状数组维护即可 , 详见代码

        时间复杂度 : O(MlogN)

[代码]

          

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 10;

struct Que
{
        int l , r , id;
} q[MAXN];

int n , c , m;
int a[MAXN] , ans[MAXN] , pre[MAXN] , nxt[MAXN];
bool visited[MAXN]; 

struct Binary_Indexed_Tree
{
        int c[MAXN];
        inline int lowbit(int x)
        {
                return x & (-x);
        }
        inline void add(int pos,int value)
        {
                if (!pos) return;
                for (int i = pos; i <= n; i += lowbit(i)) 
                        c[i] += value;
        }
        inline int query(int pos)
        {
                int ret = 0;
                if (!pos) return 0;
                for (int i = pos; i; i -= lowbit(i))
                        ret += c[i];
                return ret;
        }
        inline int query(int l,int r)
        {
                return query(r) - query(l - 1);
        }
} bit;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline bool cmp(Que a,Que b) 
{
        return a.l < b.l;
}

int main()
{
        
        read(n); read(c); read(m);
        for (int i = 1; i <= n; i++) read(a[i]);
        for (int i = n; i >= 1; i--)
        {
                if (!visited[a[i]]) 
                {
                        visited[a[i]] = true;
                        pre[a[i]] = i;
                        continue;        
                }    else
                {
                        nxt[i] = pre[a[i]];
                        pre[a[i]] = i;
                }
        }
        memset(visited,false,sizeof(visited));
        for (int i = 1; i <= n; i++)
        {
                if (!visited[a[i]])
                {
                        bit.add(nxt[i],1);
                        visited[a[i]] = true;        
                }
        }
        for (int i = 1; i <= m; i++)
        {
                read(q[i].l); read(q[i].r);
                q[i].id = i;        
        }
        sort(q + 1,q + m + 1,cmp);
        int cur = 0;
        for (int i = 1; i <= m; i++)
        {
                while (cur < q[i].l)
                {
                        bit.add(nxt[cur],-1);
                        bit.add(nxt[nxt[cur]],1);
                        ++cur;
                }
                ans[q[i].id] = bit.query(q[i].r) - bit.query(q[i].l - 1);
        }
        for (int i = 1; i <= m; i++) printf("%d\n",ans[i]);
        
        return 0;
    
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9784527.html
今日推荐