Luogu P3261 城池攻占

2022-09-21 12:12:10 字數 1206 閱讀 3868

luogu p3261 城池攻占

\(\quad\)每個城池維護乙個堆,從後往前攻占城池,不斷將無法繼續向前的騎士踢出去並標記。

\(\quad\)最後將留下來的騎士與城市的父節點的騎士團合併,繼續向前推進即可。

\(\quad\)因為有 + 和 * 所以可以打 tag 。

#include#define ll long long

#define int long long

#define double

#define fo(i,j,k) for(register int i=j;i<=k;++i)

using namespace std;

const int n=300010;

inline int read()

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

return f?-x:x;

}int ls[n],rs[n],rt[n],dist[n];

int add[n],tim[n];

int n,m;

int dep[n],die[n],ans[n],fa[n],s[n],h[n],a[n],v[n],c[n];

void pushdown(int x)

if(rs[x])

tim[x]=1;

add[x]=0;

}int merge(int x,int y)

signed main()

fo(i,1,m)

for(int i=n;i>=1;--i)

else break;

} if(i=1) break;

if(rt[i]=-1) continue ;

if(a[i]) tim[rt[i]]*=v[i],add[rt[i]]*=v[i],s[rt[i]]*=v[i];

else add[rt[i]]+=v[i],s[rt[i]]+=v[i];

pushdown(rt[i]);

if(rt[fa[i]]=-1) rt[fa[i]]=rt[i];

else rt[fa[i]]=merge(rt[fa[i]],rt[i]);

} fo(i,1,m) ans[die[i]]++;

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

fo(i,1,m)

return 0;

}

P3261 JLOI2015 城池攻占

p3261 jloi2015 城池攻占 乍一看,平衡樹?其實左偏樹更好做啦 qwq 每個節點都來棵左偏樹維護最小值,dfs 往上時合併一下,要是攻不下了就把根節點刪掉,直到能攻下,對了,攻下後值會變化怎麼辦?lazy 標記一下,和線段樹同理 include includeusing namespac...

LG P3261 JLOI2015 城池攻占

小銘銘最近獲得了一副新的桌遊,遊戲中需要用 m 個騎士攻占 n 個城池。這 n 個城池用 1 到 n 的整數表示。除 1 號城池外,城池 i 會受到另一座城池 fi 的管轄,其中 fi 每個城池有乙個防禦值 hi,如果乙個騎士的戰鬥力大於等於城池的生命值,那麼騎士就可以占領這座城池 否則占領失敗,騎...

洛谷P3261 城池攻占

臭不要臉的把 loj 的題面截圖下來 乙個顯然的思路是從葉子往上跑,將所有可以到點 x 的騎士扔進乙個小根堆裡面,然後不停彈出堆頂直到對頂元素的值不小於 h x 或者堆空了。由於需要堆合併,所以直接上左偏樹即可。至於乘和加就在堆頂打 tag,然後合併或彈出的時候再 pushdown 即可。順序顯然是...