zoukankan      html  css  js  c++  java
  • luogu题解 P3950部落冲突--树链剖分

    题目链接

    https://www.luogu.org/problemnew/show/P3950

    分析

    大佬都用LCT,我太弱只会树链剖分

    一个很裸的维护边权树链剖分题.按照套路,对于一条边(<u,v>(dep(u)<dep(v))),让它边权加1就在(v)点处+1,将边的问题转化为点的问题

    然后对于C,U操作,线段树单点修改,Q操作区间查询

    注意

    • 询问(u,v(dep(u)>dep(v)))点之间是否联通区间查询时注意是查询([u,son[v]])的和,忽然发现NOI赛场上Day2用树链剖分写得暴力为什么错了。。。

    • 单点修改注意是修改(dfn[x])那个点,查了好久的错

    代码

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    #include <iostream>
    #include <vector>
    #include <cmath>
    #define ll long long 
    #define ri register int
    using namespace std;
    template <class T>inline void read(T &x){
      x=0;int ne=0;char c;
      while(!isdigit(c=getchar()))ne=c=='-';
      x=c-48;
      while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
      x=ne?-x:x;return;
    }  
    const int maxn=300005;
    const int inf=0x7fffffff;
    struct Edge{
      int ne,to;
    }edge[maxn<<1];
    int h[maxn],num_edge=1;
    inline void add_edge(int f,int to){
      edge[++num_edge].ne=h[f];
      edge[num_edge].to=to;
      h[f]=num_edge;
    }
    int dfn[maxn],tot=0,top[maxn],dep[maxn],fa[maxn],son[maxn],size[maxn];
    void dfs_1(int now){
     int v;size[now]=1;
     for(ri i=h[now];i;i=edge[i].ne){
      	v=edge[i].to;
      	if(v==fa[now])continue;
      	fa[v]=now,dep[v]=dep[now]+1;
      	dfs_1(v);
      	size[now]+=size[v];
      	if(!son[now]||size[son[now]]<size[v])son[now]=v;
      }
      return ;
    }
    void dfs_2(int now,int t){
      int v;dfn[now]=++tot,top[now]=t;
      if(!son[now])return ;
      dfs_2(son[now],t);
      for(ri i=h[now];i;i=edge[i].ne){
      	v=edge[i].to;
      	if(v==fa[now]||v==son[now])continue;
      	dfs_2(v,v);
      }
      return ;
    }
    int sum[maxn<<2],L,R,dta,t;
    void update(int now,int l,int r){
      if(l==r){
      	sum[now]+=dta;
      	return ;
      }
      int mid=(l+r)>>1;
      if(t<=mid)update(now<<1,l,mid);
      else update(now<<1|1,mid+1,r);
      sum[now]=sum[now<<1]+sum[now<<1|1];
      return ;
    }
    int query(int now,int l,int r){
      if(L<=l&&r<=R){
      	return sum[now];
      }
      int mid=(l+r)>>1,ans=0;
      if(L<=mid)ans+=query(now<<1,l,mid);
      if(mid<R)ans+=query(now<<1|1,mid+1,r);
      //cout<<l<<' '<<r<<' '<<ans<<endl;
      return ans;
    }
    int n,m;
    struct War{
      int x,y;
    }war[maxn];
    int query_path(int x,int y){
      int tmp=0;
      while(top[x]!=top[y]){
      	if(dep[top[x]]<dep[top[y]])swap(x,y);
      	L=dfn[top[x]],R=dfn[x];
      	tmp=query(1,1,n);
      	//cout<<tmp<<endl;
      	if(tmp!=0)return 0;
      	x=fa[top[x]];
      }
      if(dep[x]>dep[y])swap(x,y);
      L=dfn[x]+1,R=dfn[y];
      if(L>R)return 1;
      tmp=query(1,1,n);//puts("f***");
      //cout<<tmp<<endl;
      if(tmp!=0)return 0;
      return 1;
    }
    inline void update_path(int x,int y,int z){
      dta=z;
      if(dep[x]<dep[y])swap(x,y);
      t=dfn[x];
      update(1,1,n);
      //L=1,R=n;
      //printf("%d
    ",query(1,1,n));
      return ;
    }
    int main(){
      char opt[5];
      int x,y,z,cnt=0;
      read(n),read(m);
      for(ri i=1;i<n;i++){
      	read(x),read(y);
      	add_edge(x,y);
      	add_edge(y,x);
      }
      dep[1]=1,fa[1]=0;
      dfs_1(1);
      dfs_2(1,1);
      memset(sum,0,sizeof(sum));
      for(ri i=1;i<=m;i++){
      	scanf("%s",opt);
      	//cout<<opt<<endl;
      	if(opt[0]=='Q'){
      	    //puts("wtf");
      		read(x),read(y);
      		//L=1,R=n;
              //printf("%d
    ",query(1,1,n));
      		if(query_path(x,y))puts("Yes");
      		else puts("No");
      	}
      	else if(opt[0]=='C'){
      		read(x),read(y);
      		war[++cnt].x=x;
      		war[cnt].y=y;
      		update_path(x,y,1);
      	}
      	else{
      		read(z);
      		x=war[z].x,y=war[z].y;
      		update_path(x,y,-1);
      	}
      }
      return 0;
    }
    
  • 相关阅读:
    LeetCode 811. Subdomain Visit Count (子域名访问计数)
    LeetCode 884. Uncommon Words from Two Sentences (两句话中的不常见单词)
    LeetCode 939. Minimum Area Rectangle (最小面积矩形)
    LeetCode 781. Rabbits in Forest (森林中的兔子)
    LeetCode 739. Daily Temperatures (每日温度)
    三种方式实现按钮的点击事件
    239. Sliding Window Maximum
    14.TCP的坚持定时器和保活定时器
    13.TCP的超时与重传
    12.TCP的成块数据流
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9351619.html
Copyright © 2011-2022 走看看