标签:i++ bit += bool dex turn tin ace 答案
讲真的,这题挺不错
首先发现QTREE系列,大力树剖
其次是第一个黑点,转化成pos到1路径上的最后一个黑点,对于每个重链用set维护
插入:
直接搞
查找:
跳链,对于一条链,如果第一个黑点的深度都大于u,那么这条链一定挂;否则更新答案
代码:
#include<bits/stdc++.h> using namespace std; const int N=100005; int n,q; int hed[N<<1],tal[N<<1],val[N<<1],nxt[N<<1],cnt=0; int son[N]={0}; int size[N]={0}; int indexy=0; int dfn[N]; int tp[N]; int id[N]; int fa[N]; int dep[N]={0}; bool islight[N]={0}; multiset<int> s[N]; int ctt=0; int be[N]; void addege(int x,int y){ cnt++; tal[cnt]=y; nxt[cnt]=hed[x]; hed[x]=cnt; } void dfs1(int u,int fat){ size[u]=1; fa[u]=fat; for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==fat) continue; dep[v]=dep[u]+1; dfs1(v,u); size[u]+=size[v]; if(size[v]>size[son[u]]){ son[u]=v; } } } void dfs2(int u,int fat,int top){ tp[u]=top; indexy++; dfn[u]=indexy; id[dfn[u]]=u; if(son[u]){ be[son[u]]=be[u]; dfs2(son[u],u,top); } for(int i=hed[u];i;i=nxt[i]){ int v=tal[i]; if(v==fat) continue; if(v==son[u]) continue; be[v]=++ctt; dfs2(v,u,v); } } void jumpy(int POS,int VAL,bool IN){ if(IN==0){ multiset<int>::iterator it=s[be[POS]].find(VAL); s[be[POS]].erase(it); } else{ s[be[POS]].insert(VAL); } } int midium(int pos){ int ans=2147483647; int u=pos; while(u){ int p=*s[be[u]].begin(); if(!s[be[u]].empty()){ if(dep[id[p]]<=dep[u]){ ans=id[p]; } } u=fa[tp[u]]; } if(ans==2147483647) ans=-1; return ans; } int main(){ scanf("%d%d",&n,&q); for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); addege(x,y); addege(y,x); } dep[0]=0; dep[1]=1; dfs1(1,1); ctt++; be[1]=1; dfs2(1,1,0); for(int i=1;i<=q;i++){ int opt,pos; scanf("%d%d",&opt,&pos); if(opt==0){ islight[dfn[pos]]^=1; if(islight[dfn[pos]]==0){jumpy(pos,dfn[pos],0);}else{jumpy(pos,dfn[pos],1);} } else{ printf("%d\n",midium(pos)); } } return 0; }
标签:i++ bit += bool dex turn tin ace 答案
原文地址:https://www.cnblogs.com/QYJ060604/p/11920538.html