[hdu 4417]树状数组+离散化+离线处理

Posted ACMsong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[hdu 4417]树状数组+离散化+离线处理相关的知识,希望对你有一定的参考价值。

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

把数字离散化,一个查询拆成两个查询,每次查询一个前缀的和。主要问题是这个数组是静态的,如果带修改操作就不能离线了。

//http://acm.hdu.edu.cn/showproblem.php?pid=4417
#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int tree[maxn];
int N;

int lowbit(int x)
{
    return x&-x;
}

void init(int n)
{
    N=n;
    for (int i=1;i<=n;i++) tree[i]=0;
}

void add(int k,int x)
{
    while (k<=N)
    {
        tree[k]+=x;
        k+=lowbit(k);
    }
}

int sum(int k)
{
    int res=0;
    while (k)
    {
        res+=tree[k];
        k-=lowbit(k);
    }
    return res;
}

vector<int> ls;
int a[maxn];

struct Query
{
    int id;
    int sgn;
    int p,j;
    int res;
    bool operator < (const Query & q) const
    {
        return p<q.p;
    }
}query[maxn*2];

int ans[maxn];

int main()
{
    int t;
    scanf("%d",&t);
    for (int cas=1;cas<=t;cas++)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        ls.clear();
        for (int i=1;i<=n;i++) ls.push_back(a[i]);
        sort(ls.begin(),ls.end());
        ls.erase(unique(ls.begin(),ls.end()),ls.end());
        for (int i=0;i<m;i++)
        {
            int l,r,h;
            scanf("%d%d%d",&l,&r,&h);
            l++;
            r++;
            int j=upper_bound(ls.begin(),ls.end(),h)-ls.begin();
            query[i*2].id=i;
            query[i*2].p=l-1;
            query[i*2].j=j;
            query[i*2].sgn=-1;
            query[i*2+1].id=i;
            query[i*2+1].p=r;
            query[i*2+1].j=j;
            query[i*2+1].sgn=1;
        }
        sort(query,query+m*2);
        init(ls.size());
        int now=0;
        for (int i=0;i<=n;i++)
        {
            if (i)
            {
                int j=lower_bound(ls.begin(),ls.end(),a[i])-ls.begin()+1;
                add(j,1);
            }
            while (now<m*2 && query[now].p==i)
            {
                query[now].res=sum(query[now].j);
                now++;
            }
        }
        memset(ans,0,sizeof(ans));
        for (int i=0;i<m*2;i++) ans[query[i].id]+=query[i].res*query[i].sgn;
        printf("Case %d:\n",cas);
        for (int i=0;i<m;i++) printf("%d\n",ans[i]);
    }
    return 0;
}

 

以上是关于[hdu 4417]树状数组+离散化+离线处理的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5249 离线树状数组求第k大+离散化

(树状数组+离线查询)HDU 4417 - Super Mario

hdu4417

CCPC河南省赛B-树上逆序对| 离线处理|树状数组 + 线段树维护逆序对 + dfs序 + 离散化

HDU 5792 World is Exploding (离散化+树状数组)

hdu 4417 Super Mario (主席树)