Super Mario&&2012 ACM/ICPC Asia Regional Hangzhou Online

来源:互联网 发布:免root备份软件 编辑:程序博客网 时间:2024/05/17 07:03

 这道题和树状数组求逆序数体很像,但是比赛的时候就是建立不好解题模型,比赛时好多人说需要离散化,看完别人的解题报告后才发现此题处理的便不是以前处理的值,这一题处理的是下标,用的是树状数组的离线算法,这题给我的感觉就是 自己的数状数组跟没学一个样,今后需要多多努力。

思路:分别对原始数组和要处理的值按从小到大排序,然后定义两个指针扫描排过序的数组,写两个条件判断,什么时候向树状数组插入,什么时候查询,

 

 

 

#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;}


 

原创粉丝点击