zoukankan      html  css  js  c++  java
  • HDU3333 Turing Tree (可持久化线段树)

    题意:

    给定一个长度为n的序列,给定m个查询,每次查询区间[L,R]范围内不同元素的和。 解决这个问题你可以使用树状数组或者莫队或者主席树

    题解:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=3e4+100;
    const int M=maxn*40;
    int n,m,q,tot;
    int a[maxn];
    int T[maxn];
    int lson[M];
    int rson[M];
    long long c[M];
    int build (int l,int r) {
        int root=tot++;
        c[root]=0;
        if (l!=r) {
            int mid=(l+r)>>1;
            lson[root]=build(l,mid);
            rson[root]=build(mid+1,r);
        }
        return root;
    }
    int up (int root,int pos,int val) {
        int newRoot=tot++;
        int tmp=newRoot;
        c[newRoot]=c[root]+val;
        int l=1,r=n;
        while (l<r) {
            int mid=(l+r)>>1;
            if (pos<=mid) {
                lson[newRoot]=tot++;
                rson[newRoot]=rson[root];
                newRoot=lson[newRoot];
                root=lson[root];
                r=mid;
            }
            else {
                rson[newRoot]=tot++;
                lson[newRoot]=lson[root];
                newRoot=rson[newRoot];
                root=rson[root];
                l=mid+1;
            }
            c[newRoot]=c[root]+val; 
        }
        return tmp;
    }
    
    long long query (int root,int l,int r,int L,int R) {
        if (l>=L&&r<=R) return c[root];
        int mid=(l+r)>>1;
        long long ans=0;
        if (L<=mid) ans+=query(lson[root],l,mid,L,R);
        if (R>mid) ans+=query(rson[root],mid+1,r,L,R);
        return ans;
    }
    
    int main () {
        int _;
        scanf("%d",&_);
        while (_--) {
            scanf("%d",&n);
            tot=0;
            for (int i=1;i<=n;i++) scanf("%d",a+i);
            map<int,int> mp;
            T[n+1]=build(1,n);
            for (int i=n;i;i--) {
                if (mp.find(a[i])==mp.end()) {
                    T[i]=up(T[i+1],i,a[i]);
                }
                else {
                    int tt=up(T[i+1],mp[a[i]],-a[i]);
                    T[i]=up(tt,i,a[i]);
                }
                mp[a[i]]=i;
            } 
            scanf("%d",&q);
            while (q--) {
                int l,r;
                scanf("%d%d",&l,&r);
                printf("%lld
    ",query(T[l],1,n,1,r));
            }
        }
    }
  • 相关阅读:
    【福利】idea最新激活码,绝对可用
    最好用的录屏工具Bandicam (班迪录屏)
    markdown改变字体、颜色和大小
    idea 2020最新破解教程(可激活至2089年)
    解决电脑桌面图标变白消失
    常见排序
    算法
    uWSGI、WSGI和uwsgi
    RabbitMQ
    flask请求和应用上下文
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13986713.html
Copyright © 2011-2022 走看看