hrbust 1625 哈理工oj ikki的数字【树状数组】

2023-10-20 10:50

本文主要是介绍hrbust 1625 哈理工oj ikki的数字【树状数组】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ikki的数字
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 29(16 users)Total Accepted: 13(12 users)Rating: Special Judge: No
Description

ikki 最近对数字颇感兴趣。现在ikki在纸上写了连续的N个数字,每个数字都是[1,N]之间任意的一个数而且不重复,即这串数字

是数字1~N的一个排列,数字的序号从1到N,现在ikki想考你一下:

在这N个数字中能找出多少个3个数的组合满足:num[x]<num[z]<num[y]且x<y<z,其中x,y,z为这三个数字的下标。

Input
多组测试数据,第一行一个整数T 表示测试数据的个数。

对于每组数据,第一行输入一个整数N表示数列中数字的个数(1<=N<=5000)

第二行输入N个数字表示一个1~N的排列。


Output

对于每组数据,输出”Case #k: p” ,k表示第k组样例,p表示满足要求的3个数字的组合数目,每组输出占一行。

由于结果可能比较大,结果需对100000007取模。

Sample Input
2
6
1 3 2 6 5 4

3 5 2 4 1


Sample Output
Case #1: 10
Case #2: 1

Author
周洲@hrbust

按照题目要求来找到三元组。

思路:

我们直接举例说明:
对于样例1:

1 3 2 6 5 4

i==1时,位子小于i的比a【i】小的数据量为:0,位子大于i的比a【i】大的数据量为:5,我们在位子大于i比a【i】大的数据中随机挑出两个组成三元组:
(1 3 2)(1 3 6)(1 3 5)(1 3 4)(1 2 6)(1 2 5)(1 2 4)(1 6 5)(1 6 4)(1 5 4)这时候不要急,我们之后会去掉不合法的情况

然后我们去掉以i为中间值不合法的情况:0*5=0;

i==2时,位子小于i的比a【i】小的数据量为:1,位子大于i的比a【i】大的数据量为:3,我们在位子大于i比a【i】大的数据中随机挑出两个组成三元组:

(3 6 5)(3 6 4)(3 5 4)

然后我们去掉以i为中间值不合法的情况:1*3:

(1 3 6)(1 3 5)(1 3 4)

i==3时,位子小于i的比a【i】小的数据量为:1,位子大于i的比a【i】大的数据量为:3,我们在位子大于i比a【i】大的数据中随机挑出两个组成三元组:

................................省略

i==4时,位子小于i的比a【i】小的数据量为:3,位子大于i的比a【i】大的数据量为:0,我们在位子大于i比a【i】大的数据中随机挑出两个组成三元组:

.................................同省略

i==5时,位子小于i的比a【i】小的数据量为:3,位子大于i的比a【i】大的数据量为:0....................

i==6时,位子小于i的比a【i】小的数据量为:3,位子大于i的比a【i】大的数据量为:0....................

按照这种方式来求得最终的三元组数一共有:10个。

题目保证了数据一定是从1~N的情况,所以我们不需要离散化,而且利用树状数组求出比a【i】小的数据是很容易的事,那么求出在a【i】后边比a【i】大的数据也很容易了。

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define mod 100000007
int n;
int a[5005];
int tree[100005];//树
int lowbit(int x)//lowbit
{return x&(-x);
}
int sum(int x)
{int sum=0;while(x>0){sum+=tree[x];x-=lowbit(x);}return sum;
}
void add(int x,int c)//加数据。
{while(x<=n){tree[x]+=c;x+=lowbit(x);}
}
int main()
{int kase=0;int t;scanf("%d",&t);while(t--){memset(tree,0,sizeof(tree));scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}int output=0;for(int i=1;i<=n;i++){int x=sum(a[i]);//求出在i之前比a[i]小的数据量个数add(a[i],1);int houda=n-a[i]-i+x+1;//推导出在i之后比a[i]大的数据量个数。output+=houda*(houda-1)/2;output-=x*houda;}printf("Case #%d: %d\n",++kase,output%mod);}
}




这篇关于hrbust 1625 哈理工oj ikki的数字【树状数组】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/246607

相关文章

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[