zoukankan      html  css  js  c++  java
  • HDU 3333--Turing Tree (线段树+离线询问处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3333

    题目大意:有n个数,m次询问,每次询问$[l,r]$中不同数的和

    Sample Input

    2
    3
    1 1 4
    2
    1 2
    2 3
    5
    1 1 2 1 3
    3
    1 5
    2 4
    3 5

    Sample Output

    1
    5
    6
    3
    6

    emmmm,看到这题。。。很明显我们可以对询问按照$r$小优先排序,然后我们将每个数丢到线段树的时候看看这个数是否出现过,如果出现过了,那么很明显,坐标越大的越优(如果$l$能够覆盖小坐标,那么一定能够覆盖大坐标),所以我们直接删除掉上一个位置的值,然后在新的位置更新该值。至于查看,我们可以用unordered_map来记录一下。

    还有就是cin,cout即使关了同步。。。也好慢的说QAQ。。。cout中用来endl跑了2500+ms,用' '代替endl跑了1500+ms,用scanf,printf跑了500+ms

    以下是AC代码:

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <iostream>
    #include <unordered_map>
    using namespace std;
    
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define lc rt<<1
    #define rc rt<<1|1
    typedef long long ll;
    const int mac=3e4+10;
    const int maxn=1e5+10;
    
    struct node
    {
        int l,r,id;
        bool operator<(const node&a)const{
            return r<a.r;
        }
    }qs[maxn];
    ll tree[mac<<2],ans[maxn];
    int a[mac];
    
    void update(int l,int r,int rt,int pos,int val)
    {
        if (l==r) {tree[rt]+=val; return;}
        int mid=(l+r)>>1;
        if (mid>=pos) update(lson,pos,val);
        else {update(rson,pos,val);}
        tree[rt]=tree[lc]+tree[rc];
    }
    
    ll query(int l,int r,int rt,int L,int R)
    {
        ll ans=0;
        if (l>=L && r<=R) return tree[rt];
        int mid=(l+r)>>1;
        if (mid>=L) ans+=query(lson,L,R);
        if (mid<R) ans+=query(rson,L,R);
        return ans;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        int t;
        cin>>t;
        while (t--){
            int n,m;
            cin>>n;
            for (int i=1; i<=n; i++)
                cin>>a[i];
            cin>>m;
            for (int i=1; i<=m; i++){
                int l,r;
                cin>>l>>r;
                qs[i]=node{l,r,i};
            }
            sort(qs+1,qs+1+m);
            memset(tree,0,sizeof tree);
            unordered_map<int,int>q;
            int st=1;
            for (int i=1; i<=m; i++){
                while (qs[i].r>=st){
                    if (q[a[st]]) update(1,n,1,q[a[st]],-a[st]);
                    update(1,n,1,st,a[st]);
                    q[a[st]]=st;
                    st++;
                }
                ans[qs[i].id]=query(1,n,1,qs[i].l,qs[i].r);
            }
            for (int i=1; i<=m; i++)
                cout<<ans[i]<<'
    ';
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    linux基础命令:alias
    linux基础命令:find
    Linux下which、whereis、locate命令的区别
    逆元知识普及(进阶篇) ——from Judge
    BZOJ 3620: 似乎在梦中见过的样子
    HDU contest808 ACM多校第7场 Problem
    P3203 [HNOI2010]弹飞绵羊 —— 懒标记?分块?LCT?...FAQ orz
    可持久化数组(线段树)[模板题]
    可持久化并(xian)查(duan)集(shu)
    主席树(静态)的轻松入门
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13274398.html
Copyright © 2011-2022 走看看