zoukankan      html  css  js  c++  java
  • CF1137F Matches Are Not a Child's Play

    一、题目

    点此看题

    二、解法

    思维含量和代码难度都点满了,但是我喜欢写这种码农题(除了插头 \(dp\)

    问题很简单,就是每次把某个节点编号变为最大的情况下维护出这个删除序列。那么我们考虑这个操作有什么特别的性质,就让小编来带你们看看吧

    无根树问题可以优先考虑定根,本题可以考虑设置编号最大的点为根,那么根一定是最后删除的。假如此时我们 up u,那么 \(u\) 到根路径的点会成为最后一个、倒数第二个、倒数第三个\(...\)也就是我们把路径上的点取出来移动到序列末尾,然后其它点的删除顺序不变。

    修改某个点到根路径可以考虑 \(\tt lct\),而我们此时可以套用染色模型,也就是修改看成某个点到根的染色,然后实边代表颜色相同,虚边代表颜色不同。那么初始的树可以依次按编号从大到小染色,遇到已经被染色的节点就停止,对于修改 up v 相当于用一种最大的新颜色处理它到根的路径。

    那么我们考虑如何通过染色来得到一个点在删除序列中的位置呢?发现就是颜色比它小的点个数 和 与它同色并且和深度比它大的点个数。第一部分可以用树状数组维护,在 \(\tt access\) 的时候在上面修改一个颜色对应的个数即可,第二部分就是在它所在的同色链中计算即可。

    时间复杂度 \(O(n\log n)\),常数因为树状数组特别地小。

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int M = 200005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    int n,m,k,UP,tot,f[M],b[M<<1];char zxy[10];
    int st[M],ch[M][2],siz[M],fa[M],col[M],cv[M],fl[M];
    struct edge
    {
    	int v,next;
    }e[M<<1];
    //tree-array
    int lowbit(int x)
    {
    	return x&(-x);
    }
    void add(int x,int c)
    {
    	for(int i=x;i<=UP;i+=lowbit(i))
    		b[i]+=c;
    }
    int ask(int x)
    {
    	int r=0;
    	for(int i=x;i>=1;i-=lowbit(i))
    		r+=b[i];
    	return r;
    }
    //link-cut-tree
    int nrt(int x)
    {
    	return ch[fa[x]][0]==x || ch[fa[x]][1]==x;
    }
    int chk(int x)
    {
    	return ch[fa[x]][1]==x;
    }
    void up(int x)
    {
    	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    }
    void flip(int x)
    {
    	if(!x) return ;
    	swap(ch[x][0],ch[x][1]);fl[x]^=1;
    }
    void cover(int x,int c)
    {
    	if(!x) return ;
    	col[x]=cv[x]=c;
    }
    void down(int x)
    {
    	if(fl[x])
    		flip(ch[x][0]),flip(ch[x][1]),fl[x]=0;
    	if(cv[x])
    		cover(ch[x][0],cv[x]),cover(ch[x][1],cv[x]),cv[x]=0;
    }
    void rotate(int x)
    {
    	int y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
    	ch[y][k]=w;fa[w]=y;
    	if(nrt(y)) ch[z][chk(y)]=x;fa[x]=z;
    	ch[x][k^1]=y;fa[y]=x;
    	up(y);up(x);
    }
    void splay(int x)
    {
    	int y=x,k=0;st[k=1]=x;
    	while(nrt(y)) y=fa[y],st[++k]=y;
    	while(k) down(st[k--]);
    	while(nrt(x))
    	{
    		int y=fa[x];
    		if(nrt(y))
    		{
    			if(chk(x)==chk(y)) rotate(y);
    			else rotate(x);
    		}
    		rotate(x);
    	}
    }
    void access(int x)//modified version
    {
    	int u=x;++k;
    	for(int y=0;x;x=fa[y=x])
    	{
    		splay(x);ch[x][1]=0;up(x);
    		add(col[x],-siz[x]);ch[x][1]=y;up(x);
    	}
    	splay(u);cover(u,k);flip(u);
    	add(col[u],siz[u]);
    }
    int qry(int x)
    {
    	splay(x);
    	return ask(col[x]-1)+siz[ch[x][1]]+1;
    }
    //dfs & initialize
    void dfs(int u,int p)
    {
    	fa[u]=p;
    	for(int i=f[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==p) continue;
    		dfs(v,u);
    	}
    }
    signed main()
    {
    	n=read();m=read();k=n;UP=n+m;
    	for(int i=1;i<=n;i++) siz[i]=1;
    	for(int i=1;i<n;i++)
    	{
    		int u=read(),v=read();
    		e[++tot]=edge{v,f[u]},f[u]=tot;
    		e[++tot]=edge{u,f[v]},f[v]=tot;
    	}
    	dfs(n,0);
    	for(int i=n,nw=n;i>=1;i--)
    	{
    		if(col[i]) continue;
    		int u=i,cnt=0,v=0;
    		while(!col[u] && u)
    			col[u]=nw,ch[u][1]=v,up(u),
    			v=u,u=fa[u],cnt++;
    		add(nw,cnt);nw--;
    	}
    	while(m--)
    	{
    		scanf("%s",zxy);
    		if(zxy[0]=='u')
    			access(read());
    		if(zxy[0]=='w')
    			printf("%d\n",qry(read()));
    		if(zxy[0]=='c')
    		{
    			int u=read(),v=read();
    			if(qry(u)<qry(v)) printf("%d\n",u);
    			else printf("%d\n",v);
    		}
    	}
    }
    
  • 相关阅读:
    DDPG
    Actor Critic
    Policy Gradients
    DQN
    Sarsa
    粘滞键
    Codeforces Round #236 (Div. 2) E. Strictly Positive Matrix 强连通
    hdu 1853 Cyclic Tour KM
    hdu 3435 A new Graph Game KM
    hdu 3488 Tour KM
  • 原文地址:https://www.cnblogs.com/C202044zxy/p/15759821.html
Copyright © 2011-2022 走看看