程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4908 BestCoder Sequence(組合數學)

HDU 4908 BestCoder Sequence(組合數學)

編輯:C++入門知識

HDU 4908 BestCoder Sequence(組合數學)


HDU 4908 BestCoder Sequence

題目鏈接

題意:給定一個序列,1-n的數字,選定一個作為中位數m,要求有多少連續子序列滿足中位數是m

思路:組合數學,記錄下m左邊和右邊一共有多少種情況大於m的數字和小於n數組的差,然後等於左邊乘右邊所有的和,然後最後記得加上左右兩邊差為0的情況。

當時也是比較逗,還用樹狀數組去搞了,其實完全沒必要

代碼:

#include 
#include 

#define lowbit(x) (x&(-x))

const int N = 40005;

int n, m, num[N], bit[N];

void add(int x, int v) {
    while (x < N) {
	bit[x] += v;
	x += lowbit(x);
    }
}

int query(int x) {
    int ans = 0;
    while (x) {
	ans += bit[x];
	x -= lowbit(x);
    }
    return ans;
}

int lb[N], ls[N], rb[N], rs[N];

int main() {
    while (~scanf("%d%d", &n, &m)) {
	memset(bit, 0, sizeof(bit));
	int v;
	for (int i = 1; i <= n; i++) {
	    scanf("%d", &num[i]);
	    if (num[i] == m)
		v = i;
	}
	memset(lb, 0, sizeof(lb));
	memset(ls, 0, sizeof(ls));
	memset(rb, 0, sizeof(rb));
	memset(rs, 0, sizeof(rs));
	for (int i = v - 1; i >= 1; i--) {
	    add(num[i], 1);
	    int small = query(m);
	    int big = v - i - small;
	    if (big >= small)
		lb[big - small]++;
	    else ls[small - big]++;
	}
	memset(bit, 0, sizeof(bit));
	for (int i = v + 1; i <= n; i++) {
	    add(num[i], 1);
	    int small = query(m);
	    int big = i - v - small;
	    if (small >= big)
		rs[small - big]++;
	    else
		rb[big - small]++;
	}
	long long ans = 1;
	ans += lb[0] + rs[0];
	for (int i = 0; i <= 40000; i++) {
	    ans += (long long)lb[i] * rs[i];
	    ans += (long long)ls[i] * rb[i];
	}
	printf("%lld\n", ans);
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved