51nod 1682 中位数计数【想法题】
来源:互联网 发布:阿里云带宽收费标准 编辑:程序博客网 时间:2024/05/16 00:55
题目:www.51nod.com/onlineJudge/questionCode.html#!problemId=1682
题意:
中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。
现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。
Input
第一行一个数n(n<=8000)
第二行n个数,0<=每个数<=10^9
Output
N个数,依次表示第i个数在多少包含其的区间中是中位数。
Input示例
5
1 2 3 4 5
Output示例
1 2 3 2 1
分析:
这题看错n的范围了,以为是6000(因为刚做了一个6000的题)….T_T…..
然后想也没想就以为是主席树模板题了,枚举每个区间,然后主席树找这个区间中位数。结果T了,时间复杂度是O(n^2logn),难道卡常数?
然后看了讨论,囧,原来看错数据范围了~~
正解是枚举每个数作为中位数x,那么这比这个数大的和比这个数小的数的数目是一样的。所以找这个中位数x所在的区间,那么对于这个数左边,统计>x和
代码:
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 2e5;int a[N], num[N], ans[N];int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) { int cnt = 0; memset(num, 0, sizeof(num)); for (int j = i; j >= 1; j--) { if (a[j] > a[i]) ++cnt; if (a[j] < a[i]) --cnt; num[8000 + cnt]++; } cnt = 0; for (int j = i; j <= n; j++) { if (a[j] > a[i]) --cnt; if (a[j] < a[i]) ++cnt; ans[i] += num[8000 + cnt]; } } for (int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' '); return 0;}
T的代码:
#include <bits/stdc++.h>using namespace std;const int MAXN = 1e4;struct Node { int L, R, sum;};Node T[MAXN * 20];int T_cnt;void insert(int &num, int &x, int L, int R) { T[T_cnt++] = T[x]; x = T_cnt - 1; ++T[x].sum; if(L == R) return ; int mid = (L + R) >> 1; if(num <= mid) insert(num, T[x].L, L, mid); else insert(num, T[x].R, mid + 1, R);}int query(int i, int j, int k, int L, int R) { if(L == R) return L; int t = T[T[j].L].sum - T[T[i].L].sum; int mid = (R + L) >> 1; if(k <= t) return query(T[i].L, T[j].L, k, L, mid); else return query(T[i].R, T[j].R, k - t, mid + 1, R);}struct A { int x, idx; bool operator < (const A &rhs) const { return x < rhs.x; }};A a[MAXN];int rk[MAXN], root[MAXN],num[MAXN];int n, m;int main() { T[0].L = T[0].R = T[0].sum = 0; root[0] = 0; scanf("%d", &n); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i].x); a[i].idx = i; } sort(a + 1, a + n + 1); for(int i = 1; i <= n; ++i) rk[a[i].idx] = i; T_cnt = 1; for(int i = 1; i <= n; ++i) { root[i] = root[i - 1]; insert(rk[i], root[i], 1, n); } for(int i=1; i<=n; i++) { num[a[i].idx]++; for(int j=i+1; j<=n; j++) { if((j-i+1)&1) num[a[query(root[i - 1], root[j], (j-i)/2+1, 1, n)].idx]++; } } for(int i=1; i<=n; i++) printf("%d ",num[i]); return 0;}
0 0
- 51nod 1682 中位数计数【想法题】
- 51nod-1682 中位数计数
- 51nod 1682 中位数计数
- 51NOD 1682 中位数计数
- 51nod-1682 中位数计数
- 51nod 1682 中位数计数
- 51nod 1682 中位数计数
- 51Nod-1682-中位数计数
- 51 nod 1682 中位数计数(前缀和)
- 51nod 1682-中位数计数(前缀和)
- 51Nod1682 中位数计数【中位数】
- 51nod 1655 染色问题(想法题)
- 51nod 1686 想法
- 51Nod-1645-中位数变换
- 集合计数 51Nod
- 中位数计数
- 中位数计数
- 中位数计数
- 文章标题
- Android 源码编译AIDL 使用实例讲解及Android Studio AIDL的调用详解
- Linux常用命令总结
- ubuntu中enable wifi为灰色的解决办法
- 获取屏幕宽高
- 51nod 1682 中位数计数【想法题】
- J2SE细节—逻辑运算符&&和--的运算顺序与优先级
- Spring中的部分需要掌握的API
- PHP学习笔记--动态网站开发所需的Web构建
- sql distinct 去重复 (mysql)
- python qt(pyqt)的文件打开、文件保存、文件夹选择对话框
- 米斯特白帽培训讲义(v2)漏洞篇 文件包含
- 蓝桥杯算法训练——未名湖边的烦恼 (递归)
- svn笔记