zoukankan      html  css  js  c++  java
  • [SCOI2015]情报传递

    [SCOI2015]情报传递

    BZOJ
    luogu
    考虑什么样的点会对某个询问贡献答案,
    设每个点的开始搜集情报时间为(t_i),那么每次询问就是要求链上有多少点i满足$$now-t_i>c$$
    移项就有$$t_i<now-c$$
    相当于求链上满足条件的点数,但是带修改依然不太好做
    我们发现对于一个询问后面的修改操作的(t_i)一定大于now,所以后面修改的点一定不影响前面询问的答案,
    想到什么?
    可以离线询问,将所有修改操作处理完,最后直接主席树查就行了,复杂度(O(nlogn))

    #include<bits/stdc++.h>
    using namespace std;
    const int _=2e5+5;
    int re(){
    	int x=0,w=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*w;
    }
    bool vis[_];
    vector<int>p[_];
    int n,o,q,cnt,tot;
    int s[_*20],ls[_*20],rs[_*20];
    int h[_],rt[_],t[_],a[_],b[_],lim[_],fa[_],f[_],lca[_],dep[_];
    struct edge{int to,next;}e[_<<1];
    void link(int u,int v){
    	e[++cnt]=(edge){v,h[u]};h[u]=cnt;
    	e[++cnt]=(edge){u,h[v]};h[v]=cnt;
    }
    int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
    void upd(int&x,int l,int r,int k){
    	s[++tot]=s[x]+1;ls[tot]=ls[x];rs[tot]=rs[x];
    	x=tot;if(l==r)return;int mid=l+r>>1;
    	k<=mid?upd(ls[x],l,mid,k):upd(rs[x],mid+1,r,k);
    }
    int query(int A,int B,int C,int D,int l,int r,int k){
    	if(r<=k)return s[A]+s[B]-s[C]-s[D];
    	int mid=l+r>>1,res=query(ls[A],ls[B],ls[C],ls[D],l,mid,k);
    	if(k>mid)res+=query(rs[A],rs[B],rs[C],rs[D],mid+1,r,k);return res;
    }
    void dfs(int u){
    	rt[u]=rt[fa[u]];
    	if(t[u])upd(rt[u],1,q,t[u]);
    	for(int i=h[u];i;i=e[i].next){
    		int v=e[i].to;if(v==fa[u])continue;
    		dep[v]=dep[u]+1;dfs(v);f[v]=u;
    	}
    	vis[u]=1;
    	for(int i=0,j=p[u].size();i<j;i++){
    		int k=p[u][i],v=a[k]==u?b[k]:a[k];
    		if(vis[v])lca[k]=find(v);
    	}
    }
    int main(){
    	n=re();
    	for(int i=1;i<=n;i++){
    		fa[i]=re();if(!fa[i])o=i;
    		link(i,fa[i]);f[i]=i;
    	}
    	q=re();int op,x;
    	for(int i=1;i<=q;i++){
    		op=re();x=re();
    		if(op==2&&!t[x])t[x]=i;
    		if(op==1){
    			a[i]=x,b[i]=re(),lim[i]=i-re()-1;
    			p[x].push_back(i);p[b[i]].push_back(i);
    		}
    	}
    	dep[1]=1;dfs(o);
    	for(int i=1;i<=q;i++)
    		if(a[i])printf("%d %d
    ",dep[a[i]]+dep[b[i]]-dep[lca[i]]-dep[fa[lca[i]]],lim[i]>=1?query(rt[a[i]],rt[b[i]],rt[lca[i]],rt[fa[lca[i]]],1,q,lim[i]):0);
    	return 0;
    }
    
  • 相关阅读:
    快速获取JOB运行结果
    快速获取DB服务器当前 MEM CPU的资源消耗
    Mongodb Sharding+Replica Set
    MongoDB replSet
    Journal工作原理
    Oracle索引梳理系列(八)- 索引扫描类型及分析(高效索引必备知识)
    Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系
    Oracle索引梳理系列(六)- Oracle索引种类之函数索引
    Oracle索引梳理系列(五)- Oracle索引种类之表簇索引(cluster index)
    Oracle索引梳理系列(四)- Oracle索引种类之位图索引
  • 原文地址:https://www.cnblogs.com/sdzwyq/p/9928812.html
Copyright © 2011-2022 走看看