HDU 2492

来源:互联网 发布:windows找不到mstsc 编辑:程序博客网 时间:2024/06/07 06:26

挺巧的一道题,笨的办法就是暴力搜索,但是用树状数组可以很巧妙的解决。

这题实质上就是每次 update 更新 val+1,然后求每段区间的长度。


#include <stdio.h>#include <iostream>#include <string.h>using namespace std;#define LEN 100002int tree[LEN+2];int in[LEN+2];int lmin[LEN+2], lmax[LEN+2], rmin[LEN+2], rmax[LEN+2];int lowbit(int x) {return x & (-x);}void update(int x) {while(x <= LEN) {tree[x]++;x += lowbit(x);}}int query(int x) {int sum = 0;while(x > 0) {sum += tree[x];x -= lowbit(x);}return sum;}int main() {int files;scanf("%d", &files);while(files--) {int n, i, j;scanf("%d", &n);for(i = 1; i <= n; i++) {scanf("%d", &in[i]);}memset(tree, 0, sizeof(tree));for(i = 1; i <= n; i++) {update(in[i]);lmin[i] = query(in[i]-1);lmax[i] = i - lmin[i] - 1;}memset(tree, 0, sizeof(tree));for(i = n, j = 1; i >= 1; i--, j++) {update(in[i]);rmin[i] = query(in[i]-1);rmax[i] = j - rmin[i] - 1;}long long ans = 0;for(i = 1; i <= n; i++) {ans += lmin[i] * rmax[i] + lmax[i] * rmin[i];}cout<< ans<< endl;}return 0;}


原创粉丝点击