其实过了【BZOJ】【4034】【HAOI2015】T2以后就好搞了……

  链修改+子树查询+换根

  其实静态树的换根直接树链剖分就可以搞了……

  因为其实只有一样变了:子树

  如果root在x的子树中(以1为根dfs的时候),那么现在x的子树就变成了整个dfs序中,除去含有root的那个子树的剩下的部分,画个图大概就是这样:(红色部分为现在的子树)

【BZOJ】【3083】遥远的国度

  我们发现,这种子树由于换根而产生变化的情况,仅当在以1为根时的树中,x是new_root的祖先时发生,那么我们判断这种情况是否发生只需这样:if (start[x]<=start[root] && end[x]>=end[root]) ......

  而其他情况?则和原来一样啦~子树并没有变化,对吧~

  那么我们就可以搞了……

 

WA了几发:这题中点权的范围是0~2147483647(P.S.我一开始还以为得开unsigned int,因为写的是$\leq2^{31}$……)所以不能认为tag=0就是没有标记,而应该用-1作为空标记……

  1 /**************************************************************
  2     Problem: 3083
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:4444 ms
  7     Memory:23172 kb
  8 ****************************************************************/
  9  
 10 //BZOJ 3083
 11 #include<cstdio>
 12 #include<cstring>
 13 #include<cstdlib>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define rep(i,n) for(int i=0;i<n;++i)
 17 #define F(i,j,n) for(int i=j;i<=n;++i)
 18 #define D(i,j,n) for(int i=j;i>=n;--i)
 19 #define pb push_back
 20 using namespace std;
 21 typedef long long LL;
 22 inline int getint(){
 23     int r=1,v=0; char ch=getchar();
 24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 26     return r*v;
 27 }
 28 const int N=100010;
 29 const int INF=2147483647;
 30 /*******************template********************/
 31 int to[N<<1],next[N<<1],head[N],cnt;
 32 void add(int x,int y){
 33     to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
 34     to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
 35 }
 36 int t[N<<2],mn[N<<2];
 37 //t[o]表示set标记
 38 #define mid (l+r>>1)
 39 #define L (o<<1)
 40 #define R (o<<1|1)
 41 void Push_down(int o,int l,int r){
 42     if (t[o]!=-1){
 43         mn[L]=mn[R]=t[L]=t[R]=t[o];
 44         t[o]=-1;
 45     }
 46 }
 47 void maintain(int o,int l,int r){
 48     mn[o]=min(mn[L],mn[R]);
 49 }
 50 void update(int o,int l,int r,int ql,int qr,int v){
 51     if (ql<=l && qr>=r) t[o]=mn[o]=v;
 52     else{
 53         Push_down(o,l,r);
 54         if (ql<=mid) update(L,l,mid,ql,qr,v);
 55         if (qr>mid) update(R,mid+1,r,ql,qr,v);
 56         maintain(o,l,r);
 57     }
 58 }
 59 int query(int o,int l,int r,int ql,int qr){
 60     if (ql>qr) return INF;
 61     if (ql<=l && qr>=r) return mn[o];
 62     else{
 63         int ans=INF;
 64         Push_down(o,l,r);
 65         if (ql<=mid) ans=min(ans,query(L,l,mid,ql,qr));
 66         if (qr>mid) ans=min(ans,query(R,mid+1,r,ql,qr));
 67         return ans;
 68     }
 69 }
 70 int n,m,rt;
 71 int a[N];
 72 int fa[N][20],st[N],ed[N],son[N],dep[N],size[N],top[N],tot;
 73 void dfs(int x){
 74     size[x]=1; son[x]=0;
 75     F(i,1,17)
 76         if (dep[x]>=(1<<i)) fa[x][i]=fa[fa[x][i-1]][i-1];
 77         else break;
 78     int mx=0;
 79     for(int i=head[x];i;i=next[i])
 80         if (to[i]!=fa[x][0]){
 81             fa[to[i]][0]=x;
 82             dep[to[i]]=dep[x]+1;
 83             dfs(to[i]);
 84             size[x]+=size[to[i]];
 85             if (size[to[i]]>mx) son[x]=to[i],mx=size[to[i]];
 86         }
 87 }
 88 bool vis[N];
 89 void connect(int x,int f){
 90     vis[x]=1; top[x]=f;
 91     st[x]=++tot;
 92     if (son[x]) connect(son[x],f);
 93  
 94     for(int i=head[x];i;i=next[i])
 95         if (!vis[to[i]])
 96             connect(to[i],to[i]);
 97     ed[x]=tot;
 98 }
 99 void modify(int x,int y,int v){
100     while(top[x]!=top[y]){
101         if (dep[top[x]]<dep[top[y]]) swap(x,y);
102         update(1,1,n,st[top[x]],st[x],v);
103         x=fa[top[x]][0];
104     }
105     if (dep[x]>dep[y]) swap(x,y);
106     update(1,1,n,st[x],st[y],v);
107 }
108  
109 int main(){
110 #ifndef ONLINE_JUDGE
111     freopen("3083.in","r",stdin);
112 //  freopen("3083.out","w",stdout);
113 #endif
114     n=getint(); m=getint();
115     F(i,2,n){
116         int x=getint(),y=getint();
117         add(x,y);
118     }
119     dfs(1);
120     connect(1,1);
121     memset(t,-1,sizeof t);
122     F(i,1,n){
123         a[i]=getint();
124         update(1,1,n,st[i],st[i],a[i]);
125     }
126     rt=getint();
127     F(i,1,m){
128         int cmd=getint();
129         if (cmd==1){
130             rt=getint();
131         }else if (cmd==2){
132             int x=getint(),y=getint();
133             int v=getint();
134             modify(x,y,v);
135         }else if (cmd==3){
136             int x=getint();
137             if (st[rt]>=st[x] && ed[rt]<=ed[x]){
138                 int y=rt,t=dep[rt]-dep[x]-1,ans=INF;
139                 D(i,17,0) if (t&(1<<i)) y=fa[y][i];
140                 if (1<=st[y]-1) ans=min(ans,query(1,1,n,1,st[y]-1));
141                 if (n>=ed[y]+1) ans=min(ans,query(1,1,n,ed[y]+1,n));
142                 printf("%d\n",ans);
143             }else{
144                 printf("%d\n",query(1,1,n,st[x],ed[x]));
145             }
146         }
147     }
148     return 0;
149 }
View Code

相关文章:

  • 2021-07-16
  • 2021-06-28
  • 2021-11-23
  • 2021-10-19
  • 2021-08-01
  • 2021-06-25
  • 2022-12-23
猜你喜欢
  • 2021-09-20
  • 2022-03-03
  • 2021-08-09
  • 2022-12-23
  • 2022-01-18
  • 2021-10-09
相关资源
相似解决方案