1. 程式人生 > >[hdu 4417]樹狀數組+離散化+離線處理

[hdu 4417]樹狀數組+離散化+離線處理

style code upper unique opera 鏈接 ems ons back

題目鏈接: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]樹狀數組+離散化+離線處理