zoukankan      html  css  js  c++  java
  • 【BZOJ3720】Gty的妹子树 块状树

    【BZOJ3720】Gty的妹子树

    我曾在弦歌之中听过你,
    檀板声碎,半出折子戏。
    舞榭歌台被风吹去,
    岁月深处尚有余音一缕……
    Gty神(xian)犇(chong)从来不缺妹子……
    他来到了一棵妹子树下,发现每个妹子有一个美丽度……
    由于Gty很哲♂学,他只对美丽度大于某个值的妹子感兴趣。
    他想知道某个子树中美丽度大于k的妹子个数。
    某个妹子的美丽度可能发生变化……
    树上可能会出现一只新的妹子……
    维护一棵初始有n个节点的有根树(根节点为1),树上节点编号为1-n,每个点有一个权值wi。
    支持以下操作:
    0 u x          询问以u为根的子树中,严格大于x的值的个数。(u^=lastans,x^=lastans)
    1 u x          把u节点的权值改成x。(u^=lastans,x^=lastans)
    2 u x          添加一个编号为"当前树中节点数+1"的节点,其父节点为u,其权值为x。(u^=lastans,x^=lastans)
    最开始时lastans=0。

    Input

    输入第一行包括一个正整数n(1<=n<=30000),代表树上的初始节点数。
    接下来n-1行,每行2个整数u,v,为树上的一条无向边。
    任何时刻,树上的任何权值大于等于0,且两两不同。
    接下来1行,包括n个整数wi,表示初始时每个节点的权值。
    接下来1行,包括1个整数m(1<=m<=30000),表示操作总数。
    接下来m行,每行包括三个整数 op,u,v:
    op,u,v的含义见题目描述。
    保证题目涉及的所有数在int内。

    Output

    对每个op=0,输出一行,包括一个整数,意义见题目描述。

    Sample Input

    2
    1 2
    10 20
    1
    0 1 5

    Sample Output

    2

    题解:这题不是用带插入区间k小值维护DFS序就行吗?然而看discuss发现空间卡得要死,于是赶紧去学又好写又好理解的分块~

    怎么做呢?插入时,如果父亲的块大小=B,那么就再开一块,否则就塞到父亲的块里。然后块内按权值排序;查询时,如果x的儿子y与x在同一块中,则暴力查询,否则直接在y的块里二分,然后递归做下去即可。

    代码还是挺短的~

    P.S:重大错误!由于本人的代码中出现了一些奇奇怪怪的错误,所以遇到菊花的数据会被卡。改进方法:在插入时,记录一下每个点儿子的块中,最后一个块是哪个,即为lastson[]。然后加入时,如果父亲节点所在块已满,则将当前节点加到lastson[fa]的块中。但是这样会导致,一个块中的点可能不连续,所以对于每个点,再开个vector记录它所有儿子的块就好了。

    P.P.S:好像还是会被卡的样子。。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #define lb(A,B) (lower_bound(s[A].begin(),s[A].end(),B,cmp)-s[A].begin())
    using namespace std;
    const int maxn=60010;
    int n,m,tot,B,cnt,CNT,ans;
    int fa[maxn],to[maxn<<1],next[maxn<<1],nb[maxn],bel[maxn],head[maxn],v[maxn],siz[maxn],TO[maxn<<1],NEXT[maxn<<1],HEAD[maxn];
    vector<int> s[maxn],ch[maxn],cs[maxn];
    inline void add(int a,int b)
    {
    	to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
    }
    inline void ADD(int a,int b)
    {
    	TO[CNT]=b,NEXT[CNT]=HEAD[a],HEAD[a]=CNT++;
    }
    inline void insert(int x)
    {
    	if(x==1)
    		nb[x]=bel[x]=++tot;
    	else	if(siz[nb[fa[x]]]==B)
    		nb[fa[x]]=nb[x]=bel[x]=++tot,cs[fa[x]].push_back(tot),ADD(bel[fa[x]],tot);
    	else
    	{
    		if(nb[fa[x]]==bel[fa[x]])	ch[fa[x]].push_back(x);
    		nb[x]=bel[x]=nb[fa[x]];
    	}
    	siz[bel[x]]++,s[bel[x]].push_back(x);
    	for(int t=siz[bel[x]]-1;t&&v[s[bel[x]][t-1]]>v[x];t--)	swap(s[bel[x]][t-1],s[bel[x]][t]);
    }
    void dfs(int x)
    {
    	insert(x);
    	for(int i=head[x];i!=-1;i=next[i])	if(to[i]!=fa[x])	fa[to[i]]=x,dfs(to[i]);
    }
    bool cmp(const int &a,const int &b)
    {
    	return v[a]<v[b];
    }
    void calc(int x,int y)
    {
    	v[0]=y+1;
    	int t=lb(x,0);
    	ans+=siz[x]-t;
    	for(int i=HEAD[x];i!=-1;i=NEXT[i])	calc(TO[i],y);
    }
    void query(int x,int y)
    {
    	ans+=(v[x]>y);
    	for(int i=0;i<(int)ch[x].size();i++)	query(ch[x][i],y);
    	for(int i=0;i<(int)cs[x].size();i++)	calc(cs[x][i],y);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    int main()
    {
    	n=rd();
    	int i,t,a,b,c,op;
    	memset(head,-1,sizeof(head)),memset(HEAD,-1,sizeof(HEAD));
    	for(i=1;i<n;i++)	a=rd(),b=rd(),add(a,b),add(b,a);
    	for(i=1;i<=n;i++)	v[i]=rd();
    	m=rd(),B=int(ceil(sqrt(double(n+m))));
    	dfs(1);
    	for(i=1;i<=m;i++)
    	{
    		op=rd(),a=rd()^ans,b=rd()^ans;
    		if(op==0)
    		{
    			ans=0;
    			query(a,b);
    			printf("%d
    ",ans);
    		}
    		if(op==1)
    		{
    			c=bel[a],t=lb(c,a),v[a]=b;
    			for(;t<siz[c]-1&&v[s[c][t+1]]<b;t++)	swap(s[c][t+1],s[c][t]);
    			if(t!=siz[c])	for(;t&&v[s[c][t-1]]>b;t--)	swap(s[c][t-1],s[c][t]);
    		}
    		if(op==2)	v[++n]=b,fa[n]=a,insert(n);
    	}
    	return 0;
    }

     

  • 相关阅读:
    一些软件设计的原则
    网站的分布式架构
    架构设计--逻辑层 vs 物理层
    社会化海量数据采集爬虫框架搭建
    面向设计原则理解
    职场中架构师面试,你会怎么回答?
    支撑5亿用户、1.5亿活跃用户的Twitter最新架构详解及相关实现
    关键路径法
    团队建设动车模型
    案例:双代号网络图在控制工程造价中的应用
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7514566.html
Copyright © 2011-2022 走看看