2 条题解

  • 3
    @ 2023-7-24 19:42:37

    image image image

    #include <bits/stdc++.h>
    using namespace std;
    const int N=200005;
    int n,m,k,s,t,tot,head[N],ROOT,x,y,q,dfn[N],sz[N];
    int ti[N],f[N][20],log2n,de[N],tot1,tot2,tr[N];
    pair<int,int> ans[N];
    struct node{
    	int y,next;	
    }e[N<<1];
    struct node1{
    	int x,y,c,id;
    	bool operator<(const node1 &k)const{
    		return c<k.c;
    	}
    }a[N];//存放询问
    struct node2{
    	int x,c;
    }b[N];//存放修改 
    inline void add(int s,int t){
    	e[++tot]={t,head[s]};head[s]=tot;
    }
    void dfs(int u,int fa){
    	dfn[u]=++tot;sz[u]=1;
    	for (int i=head[u];i;i=e[i].next){
    		int v=e[i].y;
    		de[v]=de[u]+1;
    		dfs(v,u);
    		sz[u]+=sz[v];
    	}
    }
    inline int lca(int x,int y){
    	if (de[x]<de[y]) swap(x,y);
    	for (int k=de[x]-de[y],o=0;k;k>>=1,++o)
    		if (k&1) x=f[x][o];
    	if (x==y) return x;
    	for (int j=log2n;j>=0;--j)
    		if (f[x][j]!=f[y][j]){
    			x=f[x][j];
    			y=f[y][j];
    		}
    	return f[x][0];
    }
    void change(int x,int k){
    	for (int i=x;i<=n;i+=i&(-i))
    		tr[i]+=k;
    }
    int query(int x){
    	int ans=0;
    	for (int i=x;i;i-=i&(-i))
    		ans+=tr[i];
    	return ans;
    }
    int main(){
    	cin>>n;
    	for (int i=1;i<=n;++i) {
    		cin>>k;
    		f[i][0]=k;
    		if (!k) ROOT=i;
    		else add(k,i); 
    	}
    	cin>>q;int opt;
    	for (int i=1;i<=q;++i){
    		cin>>opt;
    		if (opt==1){//询问存放在a中 
    			++tot1;
    			cin>>a[tot1].x>>a[tot1].y>>a[tot1].c;
    			a[tot1].c=i-a[tot1].c;	
    			a[tot1].id=i;
    		}		
    		else {//修改存放在b中 
    			++tot2;
    			cin>>b[tot2].x;b[tot2].c=i;
    		}
    	}
    	tot=0;
    	dfs(ROOT,0);
    	log2n=log2(n);
    	for (int j=1;j<=log2n;++j)
    		for (int i=1;i<=n;++i)
    		 	f[i][j]=f[f[i][j-1]][j-1];
    	sort(a+1,a+1+tot1);//将询问排序 
    	int l=1;
    	for (int i=1;i<=tot1;++i){
    		while (l<=tot2 && b[l].c<a[i].c){//把所有修改时刻在询问之前的插入 
    			int x=b[l].x;
    			change(dfn[x],1);
    			change(dfn[x]+sz[x],-1);
    			++l;	
    		} 
    		k=lca(a[i].x,a[i].y);
    		ans[a[i].id]=make_pair(de[a[i].x]+de[a[i].y]-de[k]*2+1,
    		query(dfn[a[i].x])+query(dfn[a[i].y])-query(dfn[k])-query(dfn[f[k][0]]));
    	}
    	for (int i=1;i<=n;++i)
    		if (ans[i].first) cout<<ans[i].first<<' '<<ans[i].second<<'\n';
    }
    
    • 1
      @ 2023-7-24 19:55:56
      #include<cstdio>
      #include<cctype>
      #include<algorithm>
      #define N 200005
      #define blank putchar(' ')
      #define nxtline putchar('\n')
      #define max(A,B) ((A)>(B)?(A):(B))
      #define min(A,B) ((A)<(B)?(A):(B))
      #define swap(A,B) ((A)^=(B)^=(A)^=(B))
      
      int ques[N][5],q;
      int n,m,cnt,pos,tot;
      int sze[N],son[N],fa[N];
      int sum[N<<2],ans[N],d[N];
      int head[N],dfn[N],top[N];
      
      struct Node{
          int x,y,z;
          int idx,ans1,ans2;
      }node[N];
      
      struct Edge{
          int to,nxt;
      }edge[N];
      
      void add(int x,int y){
          edge[++cnt].to=y;
          edge[cnt].nxt=head[x];
          head[x]=cnt;
      }
      
      bool cmp1(Node a,Node b){
          return a.idx-a.z<b.idx-b.z;
      }
      
      bool cmp2(Node a,Node b){
          return a.idx<b.idx;
      }
      
      int getint(){
          int x=0;char ch=getchar();
          while(!isdigit(ch)) ch=getchar();
          while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
          return x;
      }
      
      void write(int x){
          if(x>9) write(x/10);
          putchar(x%10+'0');
      }
      
      void first_dfs(int now){
          sze[now]=1;
          for(int i=head[now];i;i=edge[i].nxt){
              int to=edge[i].to;
              d[to]=d[now]+1;
              fa[to]=now;
              first_dfs(to);
              sze[now]+=sze[to];
              if(sze[to]>sze[son[now]])
                  son[now]=to;
          }
      }
      
      void second_dfs(int now,int low){
          top[now]=low;
          dfn[now]=++tot;
          if(son[now])
              second_dfs(son[now],low);
          for(int i=head[now];i;i=edge[i].nxt){
              int to=edge[i].to;
              if(to==son[now])
                  continue;
              second_dfs(to,to);
          }
      }
      
      void pushup(int cur){
          sum[cur]=sum[cur<<1]+sum[cur<<1|1];
      }
      
      void modify(int cur,int l,int r,int ql,int qr){
          if(l==r){
              sum[cur]=1;
              return;
          }
          int mid=l+r>>1;
          if(ql<=mid)
              modify(cur<<1,l,mid,ql,qr);
          else
              modify(cur<<1|1,mid+1,r,ql,qr);
          pushup(cur);
      }
      
      int query(int cur,int l,int r,int ql,int qr){
          if(ql<=l and r<=qr)
              return sum[cur];
          int mid=l+r>>1,ans=0;
          if(ql<=mid)
              ans+=query(cur<<1,l,mid,ql,qr);
          if(mid<qr)
              ans+=query(cur<<1|1,mid+1,r,ql,qr);
          return ans;
      }
      
      std::pair<int,int> ask(int x,int y){
          int ans=0;
          while(top[x]!=top[y]){
              if(d[top[x]]<d[top[y]])
                  swap(x,y);
              ans+=query(1,1,n,dfn[top[x]],dfn[x]);
              x=fa[top[x]];
          }
          if(d[x]<d[y])
              swap(x,y);
          ans+=query(1,1,n,dfn[y],dfn[x]);
          return std::make_pair(y,ans);
      }
      
      signed main(){
          n=getint();int root;
          for(int i=1;i<=n;i++){
              int p=0;
              if((p=getint())==0)
                  root=i;
              else
                  add(p,i);
          }
          first_dfs(root);second_dfs(root,root);
          m=getint();
          for(int i=1;i<=m;i++){
              if(getint()==1){
                  node[++pos].x=getint();
                  node[pos].y=getint();
                  node[pos].z=getint();
                  node[pos].idx=i;
              } else{
                  ques[++q][1]=getint();
                  ques[q][2]=i;
              }
          }
          std::sort(node+1,node+1+pos,cmp1);
          int now=0;
          for(int i=1;i<=pos;i++){
              while(now<q and node[i].idx-node[i].z>ques[now+1][2]){
                  now++;
                  modify(1,1,n,dfn[ques[now][1]],dfn[ques[now][1]]);
              }
              std::pair<int,int> p=ask(node[i].x,node[i].y);
              node[i].ans1=d[node[i].x]+d[node[i].y]+1-2*d[p.first];
              node[i].ans2=p.second;
          }
          std::sort(node+1,node+1+pos,cmp2);
          for(int i=1;i<=pos;i++){
              write(node[i].ans1);blank;
              write(node[i].ans2);nxtline;
          }
          return 0;
      }
      
      
      • 1

      信息

      ID
      337
      时间
      1500ms
      内存
      250MiB
      难度
      5
      标签
      递交数
      69
      已通过
      27
      上传者