你知道什么是数据结构吗?反正我不知道。

好吧今天又考试了,idy002之光不灭……考试时蜜汁样例数据坑死一片,idy估计是午觉没睡好出的题。

第一题,树状数组。

那么它的一个逆序对是一个二元组:< i; j > 满足i < j 且ai > aj,其中i; j 2 [1; n]。
我们称一个序列所包含的逆序对的个数为这个序列的逆序对数。
那么问题来了:
我给出一个长度为n 的序列,需要你计算:

a1, a2……an-1, an

aa3 ……an, a1

a3, a4……a1, a2

……

an, a1…… an-2,an-1

这n 个序列的逆序对之和。

Input
输入文件包含2 行:
第1 行1 个整数:n,表示给定序列的长度。
第2 行n 个整数:a1 a2 : : : an,表示初始序列。
Output
输出n 个序列的逆序对的和。

(样例有坑,input 3 2 2 3 output 3)

#include "cstdio"
#include "cstring"
#include "algorithm"
#define N 1000010
using namespace std;
int a[2 * N], bit[N * 24], n, m;
long long ans = 0, cur = 0;
int lowbit( int x ){
	return x & ( -x );
}
/*void modify( int pos, int delta ){
	for( int i = pos; i <= n; i += lowbit( i ) )
		bit[i] += delta;
}
int query( int rg ){
	int rt = 0;
	for( int i = rg; i; i -= lowbit( i ) )
		rt += bit[i];
	return rt;
} *//两种树状数组
void modify(int pos,int delta){
	int x=pos;
	while(x<=n){
		bit[x]+=delta;
		x+=lowbit(x);
	}
}
int query(int pos){
	int x=pos,rt=0;
	while(x){
		rt+=bit[x];
		x-=lowbit(x);
	}
	return rt;
}
int main(){
	freopen("rotinv.in", "r", stdin);
	freopen("rotinv.out", "w", stdout);
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		a[ n + i ] = a[i];
	}
	for(int i = 1; i <= n; i++){
		cur += (i - 1) -query( a[i] );
		modify( a[i], +1 );
	}
	for(int i = n + 1; i <= n + n; i++){
		modify( a[i-n], -1);
		cur += (n - 1) -query( a[i] );
		cur -= query( a[i - n] - 1 );
		modify( a[i], +1 );
		ans += cur;
	}
	printf("%I64d", ans);
	return 0;
}


第二题,不知道是什么听起来非常高端的数据结构。

你有一堆柱子,它们竖直地并排摆放在桌子上,它们的高度分别是:
h1,h2……hn-1,hn
你从前往后看,能够看见的柱子个数为这个柱子序列的“可见度”(能够看见柱子i 当且仅当hj < hi任意j < i)。
现在给你一个长度为n 的序列,还有m 个询问,每次询问某个区间[l, r] 的柱子单独拿出来后,其可见度是多大。
Input
第1 行2 个整数:n m,表示给出的柱子序列的长度和询问数。
第2 行n 个整数:a1,a2……an-1,an,表示每根柱子对应的高度。
接下来m 行,每行2 个整数:l r,表示对区间[l,r] 进行询问。

input

5 4

1 3 2 4 2

1 4

2 4

1 3

2 3

output

3

2

2

1

#include
#include
#include
#define N 100010
using namespace std;

int n,m,tot=0;
int a[N],head[N],q[N],b[N];

struct node{
	int pre,to;
}edge[N];

void adde(int from,int to){
	tot++;
	edge[tot].pre=head[from];
	edge[tot].to=to;
	head[from]=tot;
}

int dfs(int u,int r){
	for(int i=head[u];i;i=edge[i].pre){
		int v=edge[i].to;
		if(v<=r){
		    dfs(v,r);
		    tot++;
		}
	}
	return tot;
}

int main(){
	freopen("rise.in","r",stdin);
	freopen("rise.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(register int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(register int i=1;i<=n;i++){
		for(register int j=i+1;j<=n;j++){
			if(a[j]>a[i]){
				adde(i,j);
				break;
			}
		}
	}
	while(m--){
		int u,v;
		tot=1;
		scanf("%d%d",&u,&v);
		printf("%d\n",dfs(u,v));
	}
	return 0;
}



你可能感兴趣的:(数据结构)