题目链接: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: ",cas); for (int i=0;i<m;i++) printf("%d ",ans[i]); } return 0; }