Codeforces538F A Heap of Heaps【分块+差分求前缀和】

来源:互联网 发布:ubuntu16.04优化 编辑:程序博客网 时间:2024/06/01 20:38

题意:给出一个长度为n的序列,构造k(1<=k<n)叉小根堆,规定点i的父亲是(i-2)/k+1,问k叉堆中有多少个点不符合要求。

哎呀,这题很好做嘛。。你看数据是10W,然后看到(i-2)/k+1,因为整除嘛。。最多有sqrt(i-2)种取值(是吧我没说错吧?),连续一段答案会是相等的,也就是说,对于一段k在k·~(i-2)/((i-2)/k·)范围内,一个点的父亲都是同一个点QAQ。于是复杂度就是n*sqrt(n)啦。涉及到区间修改单点查询,就用差分求前缀和优化一下就好啦~哎呀这样就做出来了0.0。

算法流程:这个还用说吗QAQ,直接看代码好了0.0。
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define INF 0x3f3f3f3f#define ll long long#define N 200020 using namespace std;int data[N],n;int sum[N];int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&data[i]);}for(int i=2;i<=n;i++){int v=i-2;int j,t;for(j=1;j<=i-2;j=t+1){t=v/(v/j);if(data[(i-2)/j+1]>data[i]) sum[j]++,sum[t+1]--;}if(data[1]>data[i]) sum[i-1]++,sum[n]--;}for(int i=1;i<n;i++){sum[i]+=sum[i-1];printf("%d ",sum[i]);}return 0;}



0 0
原创粉丝点击