CQOI2009 BZOJ1303 中位数】的更多相关文章

首先找出b在数列中的位置mid 用 f[i]记录mid左边从mid往左统计比m小的数与比m大的数的差值为i的个数 用g[i]记录mid右边从mid往右统计比m大的数与比m小的数的差值为i的个数 ..有点语死早,找个样例模拟一下就懂了 var n,b,mid,k,I:longint; ans:int64; a:..] of longint; f,g:..] of longint; begin readln(n,b); to n do begin read(a[i]); if b=a[i] then…
「CQOI2009」中位数 传送门 这道题将会用到一点桶的思想. 首先我们可以在排列中先找到 \(b\) 的位置(找不到的话就直接输出 \(0\)). 然后我们从 \(b\) 的位置(设为 \(p\))开始拓展,容易发现有三种情况: \(b\) 在子段左边界 \(b\) 在子段右边界 \(b\) 在子段中间位置 我们很容易想到,对于 \(b\) 在子段边界的情况可以直接扫描,记录一下小于 \(b\) 的数和大于 \(b\) 的数的个数即可. 对于 \(b\) 在序列中间的情况可以这样做: 类比我…
baidu了一下bzoj水题列表...找到这道题.   题目大意:给定一个数t,在给定的一段包含1-n的序列中找出多少个长度为奇数子序列的中位数为t. 第一眼没看数据范围,于是开心的打了一个O(n^3)的循环,TLE....   想了想,子序列中必须包含t,所以子序列中其他数的个数必定为偶数,所以子序列中有t以及n个大于t的数和n个小于t的数(n为偶数):   因为是1-n的排列,所以也不会出现多个t的情况..   于是发现了一个很神奇的思路,对于序列里任何一个数,把小于t的数定义为-1,等于t…
[题目链接] 点击打开链接 [算法] 将小于m的数看作-1,大于m的看作1 然后求前缀和,如果区间[l,r]的中位数是m,显然有 : sum(r) - sum(l-1) = 0 因此,只需m的位置之前(后)统计每个前缀和出现的次数,然后通过乘法原理计算答案,即可 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 100010 long long i,n,m,pos,sum,opt,ans; ],r[MAXN*]; te…
先找到B的位置x,然后依次统计A[i..x-1](0<i<x)中小于B的个数,和A[x+1..i](x<i<n)中大于B的个数 最后Answer等于(左边有i个小于B的情况总数 * 右边有i个大于B的情况总数)的总和. [Code]…
由于是排列,因此b一定只出现了一次,找到出现的位置并向左右扩展考虑如何判定是否满足条件,当且仅当$[左边比b小的数ls]+[右边比b小的数rs]=[左边比b大的数lb]+[右边比b大的数rb]$,暴力枚举+线段树复杂度为$o(n^2logn)$变形上式,得到$ls-lb=rb-rs$,对两边分别处理后对应方案相乘求和即为答案 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,a[100005],s1[200005],s2[20…

XD

题目 是否完成 题目分类 简要题解 没有上司的舞会(codevs1380) Y 树形dp dp[u][0]表示不包含此节点,dp[u][1]表示包含,转移方程为 dp[u][0]+=max(dp[v][1],dp[v][0]); dp[u][1]+=dp[v][0]; http://pastebin.ubuntu.com/23112271/ [bzoj1050]舒适的路线 Y  kruskal+贪心 排序边,然后枚举权值,往下加边,每次更新答案 http://pastebin.ubuntu.co…
[BZOJ1303][CQOI2009]中位数图(模拟) 题面 BZOJ 洛谷 题解 把大于\(b\)的数设为\(1\),小于\(b\)的数设为\(-1\).显然询问就是有多少个横跨了\(b\)这个数所在的位置的区间的和恰好为\(0\).那么拿个数组记一下左边,右边直接算就好了. #include<iostream> #include<cstdio> using namespace std; #define ll long long #define MAX 100100 inlin…
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1303 题意概括 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 题解 我们找到b的位置,比如为pos. 然后往左,逐位统计比b小的,比b大的,差记为a. 对于左边所有的位置,bar[a]++,搞 n × 2 个桶.然后右边一边扫过去,一边根据桶的记录统计即可. 代码 #include <cstring> #incl…
http://www.lydsy.com/JudgeOnline/problem.php?id=1303 令c[i]表示前i个数中,比d大的数与比d小的数的差,那么如果c[l]=c[r],则[l+1,r]满足条件 #include<cstdio> #include<iostream> using namespace std; const int N=1e7; ],g[N]; void read(int &x) { x=; char c=getchar(); while(!i…