[CF538F]A Heap of Heaps && 持久化线段树

来源:互联网 发布:剑三军爷男神捏脸数据 编辑:程序博客网 时间:2024/05/29 08:45

直接枚举k 每个有儿子的节点和他的儿子区间的起点 容易发现这样枚举是调和级数 

然后需要一个东西查询某段区间比x小的数 上主席树即可

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 200000;int root[MAXN+10], A[MAXN+10], B[MAXN+10], n;struct Node {int ls, rs, sum;} ;struct Seg_Tree {Node tree[MAXN*100+10];int ncnt;void NewNode(int &i) {tree[++ncnt] = tree[i];i = ncnt;}void ins(int &i, int L, int R, int val) {NewNode(i);tree[i].sum++;if(L == R) return ;int mid = (L+R) >> 1;if(val <= mid) ins(tree[i].ls, L, mid, val);else ins(tree[i].rs, mid+1, R, val);}int query(int i, int L, int R, int l, int r) {if(l > R || r < L) return 0;if(l <= L && R <= r) return tree[i].sum;return query(tree[i].ls, L, (L+R)>>1, l, r) + query(tree[i].rs, ((L+R)>>1)+1, R, l, r);}void build(int &i, int L, int R) {NewNode(i);if(L == R) return ;int mid = (L+R) >> 1;build(tree[i].ls, L, mid);build(tree[i].rs, mid+1, R);}} seg;int query(int L, int R, int x) {if(R > n) R = n;return seg.query(root[R], 1, n, 1, x-1) - seg.query(root[L-1], 1, n, 1, x-1);}int main() {SF("%d", &n);seg.build(root[0], 1, n);for(int i = 1; i <= n; i++) SF("%d", &A[i]), B[i] = A[i];sort(B+1, B+1+n);int Len = unique(B+1, B+1+n) - (B+1);for(int i = 1; i <= n; i++) A[i] = lower_bound(B+1, B+1+Len, A[i]) - B;for(int i = 1; i <= n; i++) {root[i] = root[i-1];seg.ins(root[i], 1, n, A[i]);}for(int k = 1; k < n; k++) {LL ans = 0;for(int i = 1, j = 1; j <= n; i++, j += k)ans += query(j+1, j+k, A[i]);cout << ans << ' ';}puts("");return 0;}/*51 21 32 42 5*/


0 0
原创粉丝点击