zoukankan      html  css  js  c++  java
  • [线段树] Luogu P4346 IIIDX

    题目背景

    Osu 听过没?那是Konano 最喜欢的一款音乐游戏,而他的梦想就是有一天自己也能做个独特酷炫的音乐游戏。现在,他在世界知名游戏公司KONMAI 内工作,离他的梦想也越来越近了。

    这款音乐游戏内一般都包含了许多歌曲,歌曲越多,玩家越不易玩腻。同时,为了使玩家在游戏上氪更多的金钱花更多的时间,游戏一开始一般都不会将所有曲目公开,有些曲目你需要通关某首特定歌曲才会解锁,而且越晚解锁的曲目难度越高。

    题解

    • 先从大到小排序,每次找一个最靠左的位置,使得这个位置左边足够放下当前节点的子树

    • 若有多个值相同,应该放到最右边那个值那里

    • 显然满足单调性,毕竟如果某个位置可以满足,那么该位置右边的位置也一定能够满足

    • nxt 数组用来求同一个值的最右边在哪个位置。更新的时候向左移一个,防止取到相同的位置

    • 线段树修改的时候,最小值直接加上修改的值就行了,不用乘上区间长度,更新儿子节点的时候,要把他的父亲给他预留的位置先去掉

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <algorithm> 
     5 #define N 500010
     6 using namespace std;
     7 double k;
     8 int n,a[N],f[N],ans[N],size[N],fa[N],nxt[N],mn[N<<2],tag[N<<2];
     9 void build(int d,int l,int r)
    10 {
    11     if (l==r) { mn[d]=l; return;}
    12     int mid=l+r>>1; 
    13     build(d*2,l,mid),build(d*2+1,mid+1,r);
    14     mn[d]=min(mn[d*2],mn[d*2+1]);
    15 }
    16 void push(int d)
    17 {
    18     if (!tag[d]) return;
    19     mn[d*2]+=tag[d],mn[d*2+1]+=tag[d],tag[d*2]+=tag[d],tag[d*2+1]+=tag[d],tag[d]=0;
    20 }
    21 void change(int d,int L,int R,int x,int l=1,int r=n)
    22 {
    23     if (L<=l&&r<=R) { tag[d]+=x,mn[d]+=x; return; }
    24     int mid=l+r>>1; push(d);
    25     if (L<=mid) change(d*2,L,R,x,l,mid);
    26     if (R>mid) change(d*2+1,L,R,x,mid+1,r);
    27     mn[d]=min(mn[d*2],mn[d*2+1]);
    28 }
    29 int find(int d,int x,int l=1,int r=n)
    30 {
    31     if (l==r) return l+(mn[d]<x);
    32     int mid=l+r>>1; push(d);
    33     return x<=mn[d*2+1]?find(d*2,x,l,mid):find(d*2+1,x,mid+1,r);
    34 }
    35 int main()
    36 {
    37     scanf("%d%lf",&n,&k);
    38     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    39     sort(a+1,a+n+1),reverse(a+1,a+n+1);
    40     for (int i=n-1;i;i--) if (a[i]==a[i+1]) nxt[i]=nxt[i+1]+1;
    41     for (int i=1;i<=n;i++) fa[i]=i/k,size[i]=1;
    42     for (int i=n;i;i--) size[fa[i]]+=size[i];
    43     build(1,1,n);
    44     for (int i=1;i<=n;i++) 
    45     {
    46         if (fa[i]!=fa[i-1]) change(1,ans[fa[i]],n,size[fa[i]]-1);
    47         int p=find(1,size[i]);
    48         p+=nxt[p];nxt[p]++;p-=nxt[p]-1;ans[i]=p,change(1,p,n,-size[i]);
    49     }
    50     for (int i=1;i<=n;i++) printf("%d ",a[ans[i]]);
    51 }
  • 相关阅读:
    用wamp配置的环境,想用CMD连接mysql怎么连
    Mysql删除表
    MySQL创建表
    Leetcode 130. Surrounded Regions
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 110. Balanced Binary Tree
    Leetcode 98. Validate Binary Search Tree
    Leetcode 99. Recover Binary Search Tree
    Leetcode 108. Convert Sorted Array to Binary Search Tree
    Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11235694.html
Copyright © 2011-2022 走看看