洛谷4364 九省聯考2018 IIIDX

2021-08-18 12:16:33 字數 2988 閱讀 1379

標籤:線段樹

題目傳送門

osu 聽過沒?那是konano 最喜歡的一款**遊戲,而他的夢想就是有一天自己也能做個獨特酷炫的**遊戲。現在,他在世界知名遊戲公司konmai 內工作,離他的夢想也越來越近了。

這款**遊戲內一般都包含了許多歌曲,歌曲越多,玩家越不易玩膩。同時,為了使玩家在遊戲上氪更多的金錢花更多的時間,遊戲一開始一般都不會將所有曲目公開,有些曲目你需要通關某首特定歌曲才會解鎖,而且越晚解鎖的曲目難度越高。

這一天,konano 接到了乙個任務,他需要給正在製作中的遊戲《iiidx》安排曲目

的解鎖順序。遊戲內共有n 首曲目,每首曲目都會有乙個難度d,遊戲內第i 首曲目會在玩家pass 第⌊i

k⌋⌊ ik

⌋首曲目後解鎖(⌊x

⌋ ⌊x⌋

為下取整符號)若⌊i

k⌋⌊ ik

⌋= 0,則說明這首曲目無需解鎖

舉個例子:當k = 2 時,第1 首曲目是無需解鎖的(⌊1

2⌋⌊ 12

⌋= 0),第7 首曲目需要玩家pass 第⌊7

2⌋⌊ 72

⌋= 3 首曲目才會被解鎖。

konano 的工作,便是安排這些曲目的順序,使得每次解鎖出的曲子的難度不低於作為條件需要玩家通關的曲子的難度,即使得確定順序後的曲目的難度對於每個i 滿足di

≥d⌊i

k⌋d i≥

d⌊ik

⌋當然這難不倒曾經在資訊學競賽摸魚許久的konano。那假如是你,你會怎麼解決這份任務呢?

從檔案iiidx.in 中讀入資料。

第1 行1 個正整數n 和1 個小數k,n 表示曲目數量,k 其含義如題所示。

第2 行n 個用空格隔開的正整數d,表示這n 首曲目的難度。

輸出到檔案iiidx.out 中。

輸出1 行n 個整數,按順序輸出安排完曲目順序後第i 首曲目的難度。

若有多解,則輸出d1 最大的;若仍有多解,則輸出d2最大的,以此類推。

題意可以抽象成:給出一棵樹,使得樹上每個節點的權值都小於其子樹內點的權值,並使字典序最大

首先考慮di

d

i不相同的情況將權值從大到小排序,把長度為子樹大小的一段按子樹編號從小到大丟給它們,遞迴下去得到答案

將情況擴充套件,考慮di

d

i相同的做法

可以將編號x子樹裡乙個大的權值與編號x+

1 x+1

的子樹根的權值替換,使得x的權值依然是能取得的最大數且子樹內的數都比x的權值大,同時x+

1 x+1

子樹內的點也還能標滿≥x

+1≥ x+

1權值的權值

先把給定的權值從大到小排序,用線段樹維護每個權值左邊(包括自己)還能選取的權值的個數ci

c ici

≥siz

e[x]

c i≥

size

[x]​

如果乙個點有父親,那麼在查詢的時候要把它父親為子樹預留的大小去掉(僅去掉一次即可),具體看**實現

#include

#include

#include

#include

#include

#include

#define rep(i,a,b) for(int i=a;i<=b;i++)

#define dep(i,a,b) for(int i=a;i>=b;i--)

#define ll long long

#define mem(x,num) memset(x,num,sizeof x)

#define reg(x) for(int i=last[x];i;i=e[i].next)

using

namespace

std;

inline ll read()

while(ch>='0'&&ch<='9')

return x*f;

}//**********head by yjjr**********

#define mid ((l+r)>>1)

#define lson (x<<1)

#define rson (x<<1|1)

const

int maxn=5e5+6,inf=1e9;

struct seg_treetree[maxn<<2];

int n;double k;

int a[maxn],b[maxn],ans[maxn],size[maxn],fa[maxn],cnt[maxn];

inline

bool cmp(int a,int b)

void pushup(int x)

void pushdown(int x)

void build(int x,int l,int r)

build(lson,l,mid);build(rson,mid+1,r);

pushup(x);

}inline

int query(int x,int l,int r,int k)

void modify(int x,int l,int r,int ql,int qr,int val)

pushdown(x);

if(ql<=mid)modify(lson,l,mid,ql,qr,val);

if(qr>mid)modify(rson,mid+1,r,ql,qr,val);

pushup(x);

}int main()

rep(i,1,n)printf("%d ",a[ans[i]]);

return

0;}

p4364 九省聯考2018 IIIDX

傳送門 分析 我們先考慮如果所有數都不相同我們應該怎麼辦 我們可以直接貪心的在每個點放可行的最大權值 但是題目要求可以有相同的數 我們可以考慮每次讓當前節點可發且盡量大的同時給兄弟節點留的數盡量大 我們用線段樹維護每個點比它大的點還剩幾個 對於每個點要給它的子樹預留足夠的點即可 include in...

九省聯考 2018

發現狀態數很少,直接搜即可。不難發現這個偏序關係形成了一棵樹。本來以為直接貪心即可,即把 a 排序,然後 dfs bfs 一遍直接安排權值,類似於這樣 void dfs1 int u void dfs2 int u 不出我所料,這份簡單的 沒有過,被這組資料叉掉了 2 2.0 1 1 1 2發現這樣...

九省聯考2018遊記

day0 上午到學校,去tututu寢室,入坑荒野求生,真tm好玩 雖然只打了一把 下午坐高鐵去sh,發現sh非正式選手只有hez的。day1 開局看t1,沒意識到狀態數是個組合數,於是寫了個程式算狀態數,還寫掛了 include int n 10,m 10,f 15 15 i,j,k int ma...