HDOJ 4000 Fruit Ninja 线段树+数学

来源:互联网 发布:饭卡管理系统c语言 编辑:程序博客网 时间:2024/05/16 10:18
//HDOJ 4000 Fruit Ninja 线段树+数学/*题意:有一个数列a[],当下标满足i<j<k时候,满足a[i]<a[k]<a[j]个总数  -->x=a[i]; y=a[j]; z=a[k];  -->x<z<y思路:(线段树操作很简单,数学转化不好想)  x<z<y  -->  x<(y?z) - x<y<z; //(y?z)表示y、z大小不确定  一边更新,一边查询,每次查询O(logn)  总的时间复杂度O(nlogn)具体做法:[1]查询x前面比x大的 tmp = Query(1,1,n,x,n);  [2]Update(1,1,n,x);  [3]计算x后面比x大的 res = n-x-tmp  [4]ans1 += C(res,2)//x<(y?z)  [5]计算x前面比x小的 i-tmp//i表示当前元素前面的个数  [6]ans2 += (i-tmp)*res//y前面比y小的*y后面比y大的,即x<y<z;  [7](ans1-ans2+Mod)%Mod*/#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 100005#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define Mod 100000007int sum[N<<2];__int64 ans1,ans2;int Pushup(int rt){return sum[rt] = sum[rt<<1] + sum[rt<<1|1];}void Build(){memset(sum,0,sizeof(sum));}void Update(int rt,int l,int r,int x){if(l == r){++sum[rt];return ;}int mid = (l + r) >> 1;if(x <= mid) Update(lson,x);else Update(rson,x);Pushup(rt);}int Query(int rt,int l,int r,int L,int R){if(L <= l && R >= r){return sum[rt];}int mid = (l + r) >> 1;int res = 0;if(L <= mid) res += Query(lson,L,R);if(R > mid ) res += Query(rson,L,R);return res;}int main(){int T,n,ca = 1;int i,x;scanf("%d",&T);while(T--){Build();scanf("%d",&n);ans1 = ans2 = 0;for(i = 0; i < n; ++i){scanf("%d",&x);int tmp = Query(1,1,n,x,n);Update(1,1,n,x);__int64 res = n-x-tmp;ans1 += (res*(res-1)/2);ans1 %= Mod;ans2 += (res*(i-tmp));ans2 %= Mod;}printf("Case #%d: %I64d\n",ca++,(ans1-ans2+Mod)%Mod);}return 0;}

原创粉丝点击