[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 4417 - Super Mario
CCPC河南省赛B-树上逆序对| 离线处理|树状数组 + 线段树维护逆序对 + dfs序 + 离散化