• BZOJ 3757 苹果树 ——莫队算法


    挺好的一道题目,怎么就没有版权了呢?大数据拍过了,精神AC。。。。

    发现几种颜色这性质比较垃圾,不可加,莫队硬上。

    %了一发popoqqq大神的博客,

    看了一波VFK关于糖果公园的博客,

    又找了wjmzbmr的博客看了看块状树。

    感觉看了很多,明白了:

    还TM是抄代码舒服


    同序列上的莫队算法,只需要分块,排序之后进行统计,但是要注意更新状态的方法。

    根据VFK所说的,为了方便操作,(否则直接暴力维护会有四种情况需要讨论)

    我们统计时,把两点间的lca统一去掉,然后类似方法去维护。查询答案时加上、统计、再删去即可。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define maxn 100005
    int n,m,col[maxn],h[maxn],to[maxn],ne[maxn],en=0;
    int f[maxn][20],dep[maxn],sta[maxn],top=0,blo,cnt;
    int bel[maxn],dfsid[maxn],tot=0,hav[maxn],in[maxn];
    int nowans,ans[maxn],siz[maxn];
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    void add(int a,int b)
    {to[en]=b;ne[en]=h[a];h[a]=en++;}
    
    void dfs(int x,int fa)
    {
    	dfsid[x]=++tot;f[x][0]=fa;
    	if (siz[bel[fa]]==blo) bel[x]=++cnt;
    	else bel[x]=bel[fa];
    	siz[bel[x]]++;
    	for (int i=h[x];i>=0;i=ne[i])
    	if (to[i]!=fa){
    		dep[to[i]]=dep[x]+1;
    		dfs(to[i],x);
    	}
    }
    
    struct Query{
    	int u,v,a,b,id;
    	void gett(){
    		u=read();v=read();a=read();b=read();
    		if (dfsid[u]>dfsid[v]) swap(u,v);
    	}
    }b[maxn];
    
    bool cmp(Query x,Query y)
    {
    	return bel[x.u]==bel[y.u]?
    	bel[x.v]<bel[y.v]:bel[x.u]<bel[y.u];
    }
    
    int lca(int a,int b)
    {
    	if (dep[a]<dep[b]) swap(a,b);
    	if (a==b) return a;
    	int dist=dep[a]-dep[b];
    	D(i,15,0) if (dist&(1<<i)) a=f[a][i];
    	if (a==b) return a;
    	D(i,15,0) if (f[b][i]!=f[a][i])
    	{
    		b=f[b][i];
    		a=f[a][i];
    	}
    	return f[a][0];
    }
    
    void rev(int x)
    {
    	if (!x) return;
    	if (in[x])
    	{
    		in[x]^=1,hav[col[x]]--;
    		if (hav[col[x]]==0) nowans--;
    	}
    	else
    	{
    		in[x]^=1,hav[col[x]]++;
    		if (hav[col[x]]==1) nowans++;
    	}
    }
    
    void rever(int x,int y)
    {
    	int z=lca(x,y);
    	while (x!=z) rev(x),x=f[x][0];
    	while (y!=z) rev(y),y=f[y][0];
    }
    
    int main()
    {
    	memset(h,-1,sizeof h);
    	n=read();m=read();
    	blo=sqrt(n+1)+1e-5;
    	F(i,1,n)
    	col[i]=read();
    	F(i,1,n)
    	{
    		int a,b;
    		a=read();b=read();
    		add(a,b);add(b,a);
    	}
    	dfs(0,0); while(top)bel[sta[top--]]=cnt;
    	F(i,1,15) F(j,0,n) f[j][i]=f[f[j][i-1]][i-1];
    	F(i,1,m) b[i].gett(),b[i].id=i;
    	sort(b+1,b+m+1,cmp);
    	int nowu=0,nowv=0;
    	F(i,1,m)
    	{
    		rever(nowu,b[i].u);
    		rever(nowv,b[i].v);
    		nowu=b[i].u;nowv=b[i].v;
    		rev(lca(b[i].u,b[i].v));
    		ans[b[i].id]=nowans-(hav[b[i].a]&&hav[b[i].b]&&(b[i].a!=b[i].b));
    		rev(lca(b[i].u,b[i].v));
    	}
    	F(i,1,m) printf("%d
    ",ans[i]);
    }
    

      

  • 相关阅读:
    Multisim的电路分析方法
    转载论文关于fir滤波器的fpga实现
    verilog数组定义及其初始化
    FIR滤波器的FPGA实现方法
    matlab的fda工具使用方法
    卷积的幽默解释
    lvds配置
    latch的产生和消除
    时序优化实例
    第九篇:使用 lstat 函数获取文件信息
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6613582.html
Copyright © 2020-2023  润新知