• 动态DP


    写篇博客记录我逝去的一下午+一晚上

    过程

    学动态(DP)->学(LCT)->调啊调->对着别人代码疯狂改动->AC

    作用

    求带修改点权的多次询问的最大独立集

    朴素

    最大独立集的求解有个朴素的(DP)
    然后发现如果只考虑某一条链的贡献就可以矩阵优化

    可是怎么拆出来一条链呢?

    优化

    1.树链剖分+线段树
    2.(LCT)

    #include<cstdio>
    #include<iostream>
    #define ll long long
    using namespace std;
    const int N=3e5+50;
    const int inf=0x3f3f3f3f;
    inline int rd(register int x=0,register char ch=getchar(),register int f=0){
    	while(ch<'0'||ch>'9') f=ch=='-',ch=getchar();
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    	return f?-x:x;
    }
    struct Matrix{
    	int a[2][2];
    	friend Matrix operator * (Matrix a,Matrix b){
    		Matrix c;
    		for(int i=0;i<2;++i) for(int j=0;j<2;++j) c.a[i][j]=max(a.a[i][0]+b.a[0][j],a.a[i][1]+b.a[1][j]);
    		return c;
    	}
    }g[N];
    int v[N][2];
    void output(Matrix *a){
    	for(int i=0;i<2;++i) for(int j=0;j<2;++j) printf("%lld ",a->a[i][j]);puts("");
    }
    namespace LCT{
    	int fa[N],ch[N][2];
    	bool nroot(int x){return ch[fa[x]][0]==x||ch[fa[x]][1]==x;}
    	bool get(int x){return ch[fa[x]][1]==x;}
    	void pushup(int x){
    		g[x]=(Matrix){v[x][0],v[x][1],v[x][0],-inf};
    		if(ch[x][1]) g[x]=g[ch[x][1]]*g[x];
    		if(ch[x][0]) g[x]=g[x]*g[ch[x][0]];
    	}
    	void rotate(int x){
    		int k=get(x),prt=fa[x],gr=fa[prt];
    		if(nroot(prt)) ch[gr][get(prt)]=x;fa[x]=gr;
    		ch[prt][k]=ch[x][k^1];if(ch[x][k^1]) fa[ch[x][k^1]]=prt;
    		ch[x][k^1]=prt; fa[prt]=x;
    		pushup(prt); pushup(x);
    	}
    	void splay(int x){
    		for(;nroot(x);rotate(x)) if(nroot(fa[x])) rotate(get(x)==get(fa[x])?fa[x]:x);
    	}
    	void access(int x){
    		for(int y=0;x;y=x,x=fa[x]){
    			splay(x);
    			if(ch[x][1]) v[x][0]+=max(g[ch[x][1]].a[0][0],g[ch[x][1]].a[0][1]),v[x][1]+=g[ch[x][1]].a[0][0];
    			if(y) v[x][0]-=max(g[y].a[0][0],g[y].a[0][1]),v[x][1]-=g[y].a[0][0];
    			ch[x][1]=y; pushup(x);
    			
    		}
    	}
    }
    using namespace LCT;
    int n,typ,lastans;
    int main(){
    	//freopen("text.in","r",stdin);
    	//freopen("a.out","w",stdout);
    	n=rd()+1,typ=rd(); v[1][1]=1; pushup(1);
    	for(int i=2;i<=n;++i){
    		fa[i]=(rd()^(typ*lastans))+1; access(i); splay(i); v[i][1]=1; pushup(i);
    		printf("%d
    ",lastans=max(g[i].a[0][0],g[i].a[0][1]));
    	}
    }
    

    例题:模拟69 T2

  • 相关阅读:
    js之数组的方法
    js之选项卡
    js之数据类型的比较
    Android sharedUserId研究记录
    直接拿来用!最火的Android开源项目(一)
    [转]简约而不简单——Android SimpleAdapter
    [转]Android GC机制及一些调试信息
    sendToTarget 和 sendMessage 区别
    Android中内容观察者的使用---- ContentObserver类详解 (转)
    Inflate()
  • 原文地址:https://www.cnblogs.com/hzoi2018-xuefeng/p/12694291.html
Copyright © 2020-2023  润新知