zoukankan      html  css  js  c++  java
  • 2018牛客网暑期ACM多校训练营(第一场)J Different Integers(树状数组)

    题意

    给出一串数字以及q次查询,每次查询l,r],要求求出[1,l]和[r,n]的所有不相同的数字个数。

    分析

    先对数组进行倍增,变为两倍长,然后查询就变成一个完整的区间。离线处理,按r从小到大排序,数组从1到2n扫一遍,每次更新每种数最后出现的位置,用树状数组处理。把前一次出现位置在树状数组里面更新-1(由于r从小到大查询,为了正确求出[l,r]中的不同数字数,必须更新最新的同时把旧的删去,目的在于以最新的位置判断,避免重复),这次的位置更新+1,然后如果扫描到的i>=r则对查询区间进行求和查询。

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<set>
    #define rep(i,e) for(int i=0;i<(e);i++)
    #define rep1(i,e) for(int i=1;i<=(e);i++)
    #define repx(i,x,e) for(int i=(x);i<=(e);i++)
    #define X first
    #define Y second
    #define PB push_back
    #define MP make_pair
    #define mset(var,val) memset(var,val,sizeof(var))
    #define scd(a) scanf("%d",&a)
    #define scdd(a,b) scanf("%d%d",&a,&b)
    #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define pd(a) printf("%d
    ",a)
    #define scl(a) scanf("%lld",&a)
    #define scll(a,b) scanf("%lld%lld",&a,&b)
    #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
    #define IOS ios::sync_with_stdio(false);cin.tie(0)
    #define lc idx<<1
    #define rc idx<<1|1
    #define rson mid+1,r,rc
    #define lson l,mid,lc
    using namespace std;
    typedef long long ll;
    template <class T>
    void test(T a) {
        cout<<a<<endl;
    }
    template <class T,class T2>
    void test(T a,T2 b) {
        cout<<a<<" "<<b<<endl;
    }
    template <class T,class T2,class T3>
    void test(T a,T2 b,T3 c) {
        cout<<a<<" "<<b<<" "<<c<<endl;
    }
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const ll mod = 1e9+7;
    int T;
    void testcase() {
        printf("Case %d: ",++T);
    }
    const int MAXN = 2e5+10;
    const int MAXM = 30;
    const double PI = acos(-1.0);
    const double eps = 1e-7;
    
    struct node{
        int l,r,id;
        bool operator <(const node &b)const{
            return r<b.r;
        }
    }Q[MAXN];
    
    int n,q;
    int bit[MAXN],a[MAXN],ans[MAXN];
    int last[MAXN];
    
    int lowbit(int x){ return x&-x; }
    void update(int x,int d){
        while(x<=n){
            bit[x]+=d;
            x+=lowbit(x);
        }
    }
    int query(int x){
        int res=0;
        while(x>0){
            res+=bit[x];
            x-=lowbit(x);
        }
        return res;
    }
    int query(int l,int r){
        return query(r)-query(l-1);
    }
    
    int main() {
    #ifdef LOCAL
        freopen("data.in","r",stdin);
    #endif // LOCAL
        while(~scdd(n,q)){
            for(int i=1;i<=n;i++) scd(a[i]),a[i+n]=a[i];
    
            for(int i=0;i<q;i++){
                scdd(Q[i].l,Q[i].r);
                Q[i].id=i;
                Q[i].l+=n;
                swap(Q[i].l,Q[i].r);
            }
            n<<=1;
            sort(Q,Q+q);
            mset(last,0);
            mset(bit,0);
            int k=0;
            for(int i=1;i<=n&&k<q;i++){
                if(last[a[i]]) update(last[a[i]],-1);
                last[a[i]]=i;
                update(last[a[i]],1);
                while(k<q&&Q[k].r<=i){
                    ans[Q[k].id]=query(Q[k].l,Q[k].r);
                    k++;
                }
            }
            for(int i=0;i<q;i++){
                printf("%d
    ",ans[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    Office办公软件停止工作解决方案
    Jquery blockUI用法
    IE浏览器对js代码的高要求
    IIS中应用程序切换物理路径遇到的问题
    using关键字
    剑指offer-面试题23-链表中环的入口节点-双指针
    剑指offer-面试题22-链表中倒数第k个节点-双指针
    剑指offer-面试题21-调整数组顺序使奇数位于偶数前面-双指针
    剑指offer-面试题20-表示数值的字符串-字符串
    剑指offer-面试题19-正则表达式匹配-字符串
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9350589.html
Copyright © 2011-2022 走看看