这道题和树状数组求逆序数体很像,但是比赛的时候就是建立不好解题模型,比赛时好多人说需要离散化,看完别人的解题报告后才发现此题处理的便不是以前处理的值,这一题处理的是下标,用的是树状数组的离线算法,这题给我的感觉就是 自己的数状数组跟没学一个样,今后需要多多努力。
思路:分别对原始数组和要处理的值按从小到大排序,然后定义两个指针扫描排过序的数组,写两个条件判断,什么时候向树状数组插入,什么时候查询,
#include<iostream> #include<stack> #include<string.h> #include<string> #include<map> #include<set> #include<sstream> #include<fstream> #include<iterator> #include<vector> #include<algorithm> #include<numeric> #include<list> #define N 100010 #define lowbit(x) (x&(-x)) #define CLR(arr,val) memset(arr,val,sizeof(arr)) using namespace std; int s[N]; typedef struct node { int val; int index; }Node; typedef struct snode { int L; int R; int val; int index; }Snode; Node s1[N]; Snode s2[N]; int answer[N]; int n,m; void add(int x) { while(x<=n) { s[x]++; x+=lowbit(x); } } int sum(int x) { int ans=0; while(x>0) { ans+=s[x]; x-=lowbit(x); } return ans; } bool cmp(const Node& x,const Node& y) {return x.val<y.val;} bool cmp1(const Snode& x,const Snode& y) {return x.val<y.val;} void input(int& a) { char ch; while((ch=getchar())>'9'||ch<'0') ; for(a=0;ch>='0'&&ch<='9';ch=getchar()) a=a*10+ch-'0'; } int main() { int T; input(T); for(int k=1;k<=T;++k) { input(n),input(m); for(int i=1;i<=n;++i) input(s1[i].val),s1[i].index=i; for(int i=0;i<m;++i) input(s2[i].L),input(s2[i].R),input(s2[i].val),s2[i].L++,s2[i].R++,s2[i].index=i; sort(s1+1,s1+1+n,cmp); sort(s2,s2+m,cmp1); CLR(s,0); CLR(answer,0); int i=1,j=0; while(j<m) { while(i<=n) { if(s1[i].val>s2[j].val) break; add(s1[i].index); i++; } while(j<m) { if(i<=n&&s1[i].val<=s2[j].val) break; answer[s2[j].index]=sum(s2[j].R)-sum(s2[j].L-1); j++; } } printf("Case %d:\n",k); for(int i=0;i<m;++i) printf("%d\n",answer[i]); }return 0; }