zoukankan      html  css  js  c++  java
  • BZOJ 2743 [HEOI2012]采花 (离线+树状数组)

    题意

    1e6的数组,1e6组询问,每次问你[l,r]内有多少个数出现超过了1次
    空间128M

    思路

    主席树可以很轻松地解决这个问题,但是1e6,128M显然空间是不够的,所以我们要找别的方法
    数组长度有1e6,根号级的算法也不能使用
    我们考虑离线:
    在左端点不变时,考虑用树状数组维护右端点在不同位置时的答案,那么当左端点改变时只需要改变一次树状数组即可
    每次删去当前点a[i]的时候,那么下一个a[i]的位置到下下个a[i]的位置-1之间的点作为右端点的答案会-1,当下一个a[i]存在的时候才会有这个贡献
    所以我们处理出初始答案后离线搞就行了
    复杂度(O(nlogn))

    代码

    int n,m;
    int a[maxn];
    int c[maxn];
    void add(int x, int ad){
        if(!x)return;
        for(int i = x; i <= n; i+=lowbit(i))c[i]+=ad;
    }
    int sum(int x){
        int ans =0 ;
        for(int i = x; i; i-=lowbit(i))ans+=c[i];
        return ans;
    }
    int k;
    int vis[maxn],lst[maxn];
    int nxt[maxn],ans[maxn];
    vector<PI>v[maxn];
    int main() {
        scanf("%d %d %d", &n, &k,&m);
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            lst[i]=vis[a[i]];
            vis[a[i]]=i;
            
        }
        mem(vis,0);
        for(int i = 1; i <= n; i++){
            nxt[lst[i]]=i;
            if(!vis[a[i]]){
                if(lst[i]){vis[a[i]]=1;add(i,1);}
            }
        }
        for(int i = 1; i <= m; i++){
            int x,y;
            scanf("%d %d", &x, &y);
            v[x].pb(make_pair(y,i));
        }
        for(int i = 1; i <= n; i++){
            sort(v[i].begin(),v[i].end());
            for(int j = 0; j < (int)v[i].size(); j++){
                int y = v[i][j].fst;
                ans[v[i][j].sc]=sum(y);
            }
            int nx = nxt[i];
            int nnx = nxt[nxt[i]];
            if(nx){add(nx,-1);add(nnx,1);}
            
        }
        for(int i = 1; i <= m; i++){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }
    
  • 相关阅读:
    rest framework 之前
    python之psutil
    可持久化并查集总结
    复数学习
    主席树总结
    点分治题单(来自XZY)
    Tarjan&2-SAT 总结
    AC自动机题单
    网络流题目详讲+题单(入门版)(持续更新中......)
    网络流题目详讲+题单(提高版)(持续更新中......)
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/12964876.html
Copyright © 2011-2022 走看看