九省聯考2018 IIIDX 貪心

2021-08-18 15:58:24 字數 2433 閱讀 4625

【題目背景】

osu聽過沒?那是konano最喜歡的一款**遊戲,而他的夢想就是有一天自己也能做個獨特酷炫的**遊戲。現在

,他在世界知名遊戲公司konmai內工作,離他的夢想也越來越近了。這款**遊戲內一般都包含了許多歌曲,歌曲

越多,玩家越不易玩膩。同時,為了使玩家在遊戲上氪更多的金錢花更多的時間,遊戲一開始一般都不會將所有曲

目公開,有些曲目你需要通關某首特定歌曲才會解鎖,而且越晚解鎖的曲目難度越高。

【題目描述】

這一天,konano接到了乙個任務,他需要給正在製作中的遊戲《iiidx》安排曲目的解鎖順序。遊戲內共有n首曲目

,每首曲目都會有乙個難度d,遊戲內第i首曲目會在玩家pass第trunc(i/k)首曲目後解鎖(x為下取整符號)若tru

nc(i/k)=0,則說明這首曲目無需解鎖。舉個例子:當k=2時,第1首曲目是無需解鎖的(trunc(1/2)=0),第7首曲

目需要玩家pass第trunc(7/2)=3首曲目才會被解鎖。konano的工作,便是安排這些曲目的順序,使得每次解鎖出的

曲子的難度不低於作為條件需要玩家通關的曲子的難度,即使得確定順序後的曲目的難度對於每個i滿足di≥dtrun

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

很神奇的貪心思路。不難看出這是一棵樹,而我們要求維護乙個類似於小根堆的東西同時還要保證字典序最大,於是可以從第乙個依次地貪心考慮,這樣可以滿足字典序最大的要求。但是我們必須要使得我們的選擇是合法的,也就是如果我們選的這個點是作為了某顆子樹的根,那麼在比這個點要大(或等於)的數字裡面必須要滿足至少有size[u]個可以供選擇的數(有很多滿足條件的則選擇最大的,有重複的數則選擇最靠從大到小排序之後最靠右邊的)。

我們把di的值從大到小排序,那麼第i個數可以作為節點u的值當且僅當在i左邊的數中可供選擇的數要大於size[u],我們記fi表示第i個數前面可供選擇的數有多少個,即滿足fi>size[u]的數才可選,但是由於會有重複的數,以至於我們不知道這棵子樹中到底會選擇哪幾個節點,所以在u前面的數都有可能被選到,所以目前我們只可以把u以及u後面的數的fi全部都減去乙個size[u](因為後面的數中前面可供選擇的數的個數是確定的,不確定的只是前面的數而已),這樣的話,統計可被選擇的個數時就要看後面所有的數的可供選則的最小值了(因為這個點有可能自己本身就處在了乙個不確定的區間中)。

用線段樹維護每個點的fi就好了,如果這個點有父親的話,注意要加上父親後面可供選擇的值(因為之前減去是因為要給子樹留位置,不讓其他的點佔了,而現在開始選擇子樹中的點了),查詢的話線段樹上二分就可了。

/**************************===

* author : ylsoi

* problem : iiidx

* algorithm : tanxin

* time : 2018.4.12

* *************************=*/

#include

#include

#include

#include

#include

using

namespace

std;

void file()

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

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

#define mrep(i,x) for(register int i=beg[x];i;i=e[i].last)

#define ll long long

#define inf (0x3f3f3f3f)

const

int maxn=5e5+10;

struct segmen_tree

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

build(lson);

build(rson);

pushup(rt);

}void update(int rt,int l,int r,int l,int r,int x)

else

}int query(int rt,int l,int r,int x)

}t;int n,d[maxn],cnt,beg[maxn],be[maxn],pos[maxn],cnt_be,size[maxn],ans[maxn];

double k;

bool cmp(int x,int y)

struct edgee[maxn];

void add(int u,int v)

void get_size(int u)

}int main()

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

return

0;}

九省聯考2018 IIIDX 貪心 線段樹

題面 題解 首先有乙個比較明顯的50分貪心 先把d排好序,然後按從小到大的順序貪心的給每個點選值,同等條件下優先編號大的,於是越小的值會越趨近於放在編號越大的上面。但是這樣在數字重複的情況下是不對的,比如下面這組資料 4 3.0 1 1 2 2 貪心會得到1 1 2 2 而正確答案是1 2 2 1....

九省聯考2018 IIIDX 線段樹 貪心

給出 k 和 n 個數,構造乙個序列使得 d i d i k 並且字典序最大。聽說,當年省選的時候,這道題擋住了大批的高手,看上去十分簡單,實際上那道彎段時間內是轉不過來的。首先,乙個套路是,將這個序列的關係抽象成一棵樹,i的父親是floor i k 我們要要求子樹內部的點的權值都比父親大。我們觀察...

2472 九省聯考 2018 IIIDX

一眼思路的題 就是比較難寫.考慮乙個點必須小於其 i dk id k 那麼容易想出乙個樹形結構,每個點都大於其父親.那麼對於乙個點,那麼他能選取的最大值就是當前能選的所有點中的n size id n s ize id 這個點的值。然後留夠其兒子的位置即可。最後如果有相同的點,容易想到把當前點放在權值...