zoukankan      html  css  js  c++  java
  • [BZOJ3653]谈笑风生 主席树

    题面

    这道题应该比较裸吧。

    (a),(b)都是(c)的祖先。

    那么第一种情况是(b)(a)的祖先,那么方案数就是(min{dep[a]-1,k}cdot (num[a]-1))

    第二种是(a)(b)的祖先,那么方案数是

    [sum_{cin subtree(a),dep[c]-dep[a]leq k} num[c]-1 ]

    显然这东西用主席树,一个维度是dfs序,一个维度数深度维护一下就好了吧。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #define REP(i,a,n) for(register int i(a);i<=(n);++i)
    #define FEC(i,x,y) for(register int i=head[x],y=g[i].to;i;i=g[i].ne,y=g[i].to)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    const int SZ=(1<<21)+1;char ibuf[SZ],*iS,*iT,obuf[SZ+128],*oS=obuf,*oT=obuf+SZ-1;
    #ifdef ONLINE_JUDGE
    #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SZ,stdin),(iS==iT?EOF:*iS++)):*iS++)
    #else
    #define gc() getchar()
    #endif
    template<typename I>inline void read(I&x){char c=gc();int f=0;for(;c<'0'||c>'9';c=gc())c=='-'?f=1:0;for(x=0;c>='0'&&c<='9';c=gc())x=(x<<1)+(x<<3)+(c&15);f?x=-x:0;}
    inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
    #define printf(...) (oS>oT&&(flush(),1),oS+=sprintf(oS,__VA_ARGS__))
    template<typename A,typename B>inline char SMAX(A&a,const B&b){return a<b?a=b,1:0;}
    template<typename A,typename B>inline char SMIN(A&a,const B&b){return a>b?a=b,1:0;}
    typedef long long ll;typedef unsigned long long ull;typedef std::pair<int,int>pii;
    
    const int N=300000+7;
    int n,Q,x,y,dfn[N],pre[N],dfc,dep[N],num[N],a[N],T;
    struct Edge{int to,ne;}g[N<<1];int head[N],tot;
    inline void Addedge(int x,int y){g[++tot].to=y;g[tot].ne=head[x];head[x]=tot;}
    
    inline void DFS(int x,int fa=0){
    	dfn[x]=++dfc;pre[dfc]=x;dep[x]=dep[fa]+1;num[x]=1;
    	FEC(i,x,y)if(y!=fa)DFS(y,x),num[x]+=num[y];
    }
    
    struct Node{int lc,rc,id;ll val;}t[N*21];int RT[N],nod;
    inline void Insert(int&o,int L,int R,int x,int k){
    	if(t[o].id!=T)t[++nod]=t[o],t[o=nod].id=T;t[o].val+=k;if(L==R)return;
    	int M=(L+R)>>1;x<=M?Insert(t[o].lc,L,M,x,k):Insert(t[o].rc,M+1,R,x,k);
    }
    inline ll Query(int o,int p,int L,int R,int l,int r){
    	if(l<=L&&R<=r)return t[o].val-t[p].val;
    	int M=(L+R)>>1;if(r<=M)return Query(t[o].lc,t[p].lc,L,M,l,r);if(l>M)return Query(t[o].rc,t[p].rc,M+1,R,l,r);
    	return Query(t[o].lc,t[p].lc,L,M,l,r)+Query(t[o].rc,t[p].rc,M+1,R,l,r);
    }
    
    inline char cmp(const int&x,const int&y){return dep[x]<dep[y];}
    int main(){
    	read(n);read(Q);REP(i,1,n-1)read(x),read(y),Addedge(x,y),Addedge(y,x);
    	DFS(1);REP(i,1,n)a[i]=i;std::sort(a+1,a+n+1,cmp);int p=1;
    	REP(i,1,n){
    		++T;RT[i]=RT[i-1];
    		while(p<=n&&dep[a[p]]==i)Insert(RT[i],1,n,dfn[a[p]],num[a[p]]-1),++p;//错误笔记:这里的i,p要分清楚不能弄混掉了
    	}
    	REP(i,1,Q){
    		read(x),read(y);//错误笔记:同第49行,i,x要分清楚 
    		printf("%lld
    ",std::min(dep[x]-1,y)*(ll)(num[x]-1)+Query(RT[std::min(dep[x]+y,n)],RT[dep[x]],1,n,dfn[x],dfn[x]+num[x]-1));//错误笔记:要把dep[x]+y和n取个min,不然的话还没更新过
    	}return flush(),0;
    }
    
  • 相关阅读:
    Maven 集成Tomcat插件
    dubbo 序列化 问题 属性值 丢失 ArrayList 解决
    docker 中安装 FastDFS 总结
    docker 从容器中拷文件到宿主机器中
    db2 相关命令
    Webphere WAS 启动
    CKEDITOR 4.6.X 版本 插件 弹出对话框 Dialog中 表格 Table 自定义样式Style 问题
    SpringMVC JSONP JSON支持
    CKEDITOR 3.4.2中 按钮事件中 动态改变图标和title 获取按钮
    git回退到远程某个版本
  • 原文地址:https://www.cnblogs.com/hankeke/p/BZOJ3653.html
Copyright © 2011-2022 走看看