JLOI2015 左偏樹 城池攻占

2022-05-24 13:57:10 字數 1571 閱讀 4406

題目鏈結

考慮每個節點建乙個以騎士攻擊力為關鍵字的小根堆,從葉子節點向上掃瞄,每次彈堆至堆頂騎士攻擊力大於當前城池防禦力,可以採用左偏樹維護,

對於城池的攻擊力改變值,可以借用線段樹區間修改的懶標記思想,打上乘法及加法標記,每次涉及到改變堆結構的操作前下放標記即可。

稍微卡常之後可過

**

# include # include # define maxn 300005

struct edgee[maxn];

int hd[maxn], cnte;

struct heaphp[maxn];

struct knightkn[maxn];

struct cityct[maxn];

int death[maxn], destory[maxn];

templatevoid rd(t & x);

void adde(int u, int v);

void dfs(int now, int fa);

int merge(int x, int y);

void pushdown(int now);

void calc(int now, long long mul, long long pls);

// int find(int x);

int main()

for(int i = 2, tmp; i <= n; i++)

for(int i = 1; i <= m; i++)

dfs(1, 0);

while(hp[1].rt)

for(int i = 1; i <= n; i++)

for(int i = 1; i <= m; i++)

return 0;

}// int find(int x)

void calc(int now, long long mul, long long pls)

}void pushdown(int now)

int merge(int x, int y)

pushdown(x); pushdown(y);

if(kn[x].pow > kn[y].pow)

hp[x].rs = merge(hp[x].rs, y);

if(hp[hp[x].ls].dis < hp[hp[x].rs].dis)

hp[x].dis = hp[hp[x].rs].dis + 1;

return x;

}void dfs(int now, int fa)

while(hp[now].rt && kn[hp[now].rt].pow < ct[now].def)

if(ct[now].ai)

else

}void adde(int u, int v)

templatevoid rd(t & x)

} for( ; isdigit(ch); ch = getchar())

x *= fl;

}

JLOI2015 城池攻占 左偏樹

表示調這道題已經調到失智了。因為昨天剛寫完線段樹2,所以pushdown就寫得和線段樹2一模一樣,於是,成功的在pushdown的地方,各種錯 下面講做法 首先我們可以觀察到每個騎士都是獨立的,因此對於每個城池我們可以建乙個堆,堆中維護的是在這個城池的騎士。維護乙個小根堆,所以如果堆頂的騎士攻擊力不...

JLOI2015 城池攻占

霧.改變操作乘法是沒有負數的,那麼就不會改變大小關係,我們就可以dfs樹,然後用可合併堆進行操作。splay 啟發式合併也可以過 luogu 3261 bzoj 4003 include include include define int long long const int maxm 3100...

JLOI2015 城池攻占

點此看題 先把每個人放到對應的點上,可以用左偏樹,然後從下往上合併,每次就刪除當前節點會犧牲的人,然後維護乙個 加法 乘法 標記,時間複雜度o n log n o n log n o nlogn include include using namespace std define int long ...