HDU4000Fruit Ninja【树状数组+组合数】

大意:

告诉你一个有n个数的序列 (1 -- n) 问其中有多少组 (a[i], a[j], a[k]) 满足i < j < k 并且 a[i] < a[k] < a[j]

分析:

这个题跟那个中间为峰值的题很像   我的第一反应为树状数组

求的就是在这个序列当中  小大中 一共会出现多少次

小大中 = (小中大 + 小大中) — 小中大

(小中大 + 小大中) 也就是说只要前面这个数是小的  后面的大的数中任取两个就可以了

用两个数组来维护

一个qian[]用来存前边有多少个小于这个数  另一个hou[]维护后面有多少个大于这个数

小中大的个数就是  sum(qian[i] * hou[i])==

求小XX的过程中我脑袋抽筋了

我一开始用的是这种思路

对于每一位

用比它小的个数 * (C(大于它的g个数, 2))

看起来貌似很合理

但是其实有个严重的问题

在求小中大的过程我们可以那么考虑是因为中间的是唯一的

所以无论我们怎么成都不会重复

但是这个若只是考虑小于它的和大于等于它的想成就会出现重复的

怎么避免重复呢

只要按照求小中大的思路

我们可以确定一个最小的  那么  之后的就是以这个为基准的 而不会出现重复

小XX = sum(C(大于该位, 2) );

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const long long maxn = 100005;
 7 const long long mod = 100000007;
 8 long long c[maxn];
 9 long long n, a[maxn];
10 long long qian[maxn], hou[maxn], hh[maxn];
11
12 long long lowbit(long long x) {
13     return x & ( - x ) ;
14 }
15
16 void add(long long i) {
17     while(i <= n) {
18         c[i] += 1;
19         i += lowbit(i);
20     }
21 }
22
23 long long sum(long long i) {
24     long long s = 0;
25     while(i > 0) {
26         s += c[i];
27         i -= lowbit(i);
28     }
29     return s;
30 }
31
32 void init() {
33     memset(c, 0, sizeof(c));
34     for(long long i = 1; i <= n; i++) {
35         qian[i] = sum(a[i]);
36         add(a[i]);
37     }
38     memset(c, 0, sizeof(c));
39     for(long long i = n; i >= 1; i--) {
40         add(a[i]);
41         hou[i] = n - i + 1 - sum(a[i]);
42     }
43 }
44
45 int main() {
46     long long t;
47     scanf("%I64d",&t);
48     for(long long kase = 1; kase <= t; kase++) {
49         scanf("%I64d",&n);
50         for(long long i = 1; i <= n; i++) scanf("%I64d",&a[i]);
51         init();
52         long long sum1 = 0;
53         for(long long i = 1; i <= n; i++) {
54             sum1 += qian[i] * hou[i];
55             sum1 %= mod;
56         }
57         long long sum2 = 0;
58         for(long long i = 1; i <= n; i++) {
59             sum2 += (hou[i] * (hou[i] - 1) / 2);
60             sum2 %= mod;
61         }
62         printf("Case #%I64d: ", kase);
63         long long ans = (sum2 - sum1 + mod) % mod;
64         printf("%I64d\n", ans);
65     }
66     return 0;
67 }

时间: 2024-12-28 23:22:27

HDU4000Fruit Ninja【树状数组+组合数】的相关文章

hdu 4000Fruit Ninja 树状数组

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2048    Accepted Submission(s): 805 Problem Description Recently, dobby is addicted in the Fruit Ninja. As you know, dobby is a free elf, so unlik

[luogu2154 SDOI2009] 虔诚的墓主人(树状数组+组合数)

传送门 Solution 显然每个点的权值可以由当前点上下左右的树的数量用组合数\(O(1)\)求出,但这样枚举会T 那么我们考虑一段连续区间,对于一行中两个常青树中间的部分左右树的数量一定,我们可用树状数组求区上下贡献值和,相乘就得到了当前区间的贡献. 有思路调不出来系列 Code #include <cmath> #include <cstdio> #include <cstring> #include <cstdlib> #include <io

Fruit Ninja(树状数组+思维)

Fruit Ninja Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2164    Accepted Submission(s): 838 Problem Description Recently, dobby is addicted in the Fruit Ninja. As you know, dobby is a free e

hdu 4000 Fruit Ninja 树状数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4000 Recently, dobby is addicted in the Fruit Ninja. As you know, dobby is a free elf, so unlike other elves, he could do whatever he wants.But the hands of the elves are somehow strange, so when he cuts

hdu 4000 Fruit Ninja(树状数组)

题目大意是给定一串1到n的排列(设为数组a),求其中满足a[x]<a[z]<a[y]的排列个数,其中x<y<z 直接求这样的排列个数并不好求,我们可以转化为求a[x]<a[z]<a[y]+a[x]<a[y]<a[z]的个数减去a[x]<a[z]<a[y]的个数 用left数组记录i位置前比a[i]小的元素个数,left数组可由树状数组预处理得到,那么我们可以得到求排列个数的公式(具体见码) #include<cstdio> #incl

求逆序数数目(树状数组+离散化)

404在玩忍者印记(Mark of the Ninja)操纵忍者时遇到这样一个场景,两栋大楼之间有许多绳索,从侧面看,就像这个样子: 我们的忍者非常有好奇心,他可以观察到每个绳索的端点在两栋楼的高度,想知道这些绳索有多少个交点(图中黑色的点).他观察到不会建筑上不会有一点上有两个绳索,并且没有三条绳索共点. 输入描述 第一行:整数T,代表有T组数据. (1 <= T <= 100) 下一行:整数N,代表有N条绳索. (1 <= N <= 100000) 接下来Na行给出两个整数A_

cdoj841-休生伤杜景死惊开 (逆序数变形)【线段树 树状数组】

http://acm.uestc.edu.cn/#/problem/show/841 休生伤杜景死惊开 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 陆伯言军陷八卦阵之中,分明只是一条直路,却怎的也走不到尽头.阵中尽是石堆,以某一石堆为参考,无论向走还是向右,总是会回到出发的石堆,最后幸得一黄姓老翁带路才得脱出. 陆伯言逃离八卦阵后,来到山顶观察此

POJ 3378——Crazy Thairs(树状数组+dp+高精度)数据结构优化的DP

Crazy Thairs Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6598   Accepted: 1636 Description These days, Sempr is crazed on one problem named Crazy Thair. Given N (1 ≤ N ≤ 50000) numbers, which  are no more than 109, Crazy Thair is a g

BZOJ 1227 [SDOI2009] 虔诚的墓主人 离线+树状数组+离散化

鸣谢:140142耐心讲解缕清了我的思路 题意:由于调这道题调的头昏脑涨,所以题意自己搜吧,懒得说. 方法:离线+树状数组+离散化 解析:首先深表本蒟蒻对出题人的敬(bi)意(shi).这道题简直丧心病狂,看完题后大脑一片空白,整个人都不好了,刚开始的思路是什么呢?暴力思想枚举每个墓碑,然后计算每个墓碑的虔诚度,然后再来统计.不过看看数据范围呢?10^9*10^9的矩阵,最多才10^5个树,光枚举就已经超时了,所以肯定不行.(不过要是考试真没思路我就那么搞了- -!) 然后也想到来枚举墓碑,不过