洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)
生活随笔
收集整理的這篇文章主要介紹了
洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
被\(STL\)坑害了一個晚上,真的菜的沒救了啊。
準確的說是一個叫\(reverse\ iterator\)的東西,就是我們經常用的\(rbegin()\)
有一個非常重要的性質
在反向迭代器中,++相當于正常的--,--相當于正常的++
也就是說
假設我們要訪問\(set\)中的倒數第二個元素,我們要\(++s.rbegin()\)
而不是一些別的東西
好
我們回到這個題,對于這個題目來說,其實我的第一反應是虛樹,QWQ但事實證明,并不能用虛樹來解決這個問題。
我們可以通過一些方式,發現,無論從哪個有寶藏的點出發,訪問所有點的總距離都是一定的。那么我們可以強制按照\(dfn\)順序,每個點從\(dfn\)的上一個節點走過來,然后走向\(dfn\)的下一個節點,那么刪除的之后,我們要是知道每個點的前驅和后繼的話,就可以考慮直接更新\(ans\)了,(但是要特判第一個點和最后一個點,第一個點的前驅是最后一個點,最后一個點的后繼是第一個點)
那么既然需要一個排序+前驅后繼的數據結構,自然就是\(set\)了
不過需要注意的是。
\(rbegin()\)的問題!!!!!!!!!!!!!!
直接給代碼了
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> #include<set> #define mk makr_pair #define ll long long #define int long long using namespace std; inline int read() {int x=0,f=1;char ch=getchar();while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f; } const int maxn = 2e5+1e2; const int maxm = 2*maxn; const int inf = 1e9; int point[maxn],nxt[maxm],to[maxm]; int cnt,n,m; int dfn[maxn],deep[maxn],f[maxn][21]; set<int> s; int tot; int dis[maxn]; int mp[maxn]; int ans; int val[maxm],tag[maxn]; void addedge(int x,int y,int w) {nxt[++cnt]=point[x];to[cnt]=y;val[cnt]=w;point[x]=cnt; } void dfs(int x,int fa,int dep) {deep[x]=dep;dfn[x]=++tot;mp[tot]=x;for (int i=point[x];i;i=nxt[i]){int p = to[i];if (p==fa) continue;f[p][0]=x;dis[p]=dis[x]+val[i];dfs(p,x,dep+1);} } void init() {for (int j=1;j<=20;j++)for (int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1]; } int go_up(int x,int d) {for (int i=0;i<=20;i++)if ((1<<i) & d) x=f[x][i];return x; } int lca(int x,int y) {if (deep[x]>deep[y]) x=go_up(x,deep[x]-deep[y]);else y=go_up(y,deep[y]-deep[x]);if (x==y) return x;for (int i=20;i>=0;i--){if (f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}}return f[x][0]; } int getdis(int x,int y) {return dis[x]-2*dis[lca(x,y)]+dis[y]; } int getpre(int x) {set<int> :: iterator it = s.lower_bound(x);--it;if ((*it)==-inf) return mp[*(++s.rbegin())];else return mp[(*it)]; } int getlas(int x) {set<int> :: iterator it = s.upper_bound(x);if ((*it)==inf) return mp[*(++s.begin())];else return mp[(*it)]; } signed main() {//freopen("game.in.txt","r",stdin);//freopen("game.out","w",stdout);n=read();m=read();for (int i=1;i<n;i++){int x=read(),y=read(),w=read();addedge(x,y,w);addedge(y,x,w);}dfs(1,0,1);init();s.insert(inf);s.insert(-inf);for (int i=1;i<=m;i++){int x=read();if (tag[x]){int pre = getpre(dfn[x]);int last = getlas(dfn[x]);// cout<<"you:"<<pre<<" "<<last<<endl;ans=ans-getdis(pre,x)-getdis(last,x);ans=ans+getdis(pre,last);s.erase(dfn[x]);tag[x]=0;}else{if (s.size()==2) {s.insert(dfn[x]);tag[x]=1;cout<<ans<<"\n";continue;}int pre = getpre(dfn[x]); //cout<<1<<endl; int last = getlas(dfn[x]);// cout<<"meiyou:"<<pre<<" "<<last<<" "<<getdis(pre,x)<<" "<<lca(pre,x)<<" "<<dis[pre]<<" "<<dis[x]<<endl;ans=ans-getdis(pre,last);ans=ans+getdis(pre,x)+getdis(last,x);s.insert(dfn[x]);tag[x]=1;}cout<<ans<<"\n";}return 0; }轉載于:https://www.cnblogs.com/yimmortal/p/10161533.html
總結
以上是生活随笔為你收集整理的洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java Spring MVC框架搭建(
- 下一篇: 下一个更大元素 I(LeetCode 4