社区讨论

求助

P2146[NOI2015] 软件包管理器参与者 7已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi7wgxf3
此快照首次捕获于
2025/11/21 04:44
4 个月前
此快照最后确认于
2025/11/21 04:44
4 个月前
查看原帖
珂朵莉树本机可过第一个下载数据,但是交上去全re+tle
code
CPP
#include<bits/stdc++.h>
#define N 500005
#define IT set<Node>::iterator
using namespace std;
int n,m;
int fa[N],top[N],seg[N],son[N],size[N];
struct Edge
{
	int next,to;
}edge[N*4];int head[N],cnt;
void add_edge(int from,int to)
{
	edge[++cnt].next=head[from];
	edge[cnt].to=to;
	head[from]=cnt;
}

template <class T>
void read(T &x)
{
	char c;int sign=1;
	while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
	while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
}

struct Node 
{
    int l,r;
    mutable int v;
    bool operator < (const Node &a) const 
	{
        return l < a.l;
    }
    Node(int l, int r =-1, int v=0) : l(l), r(r), v(v) {} 
};
set<Node> s;
IT split(int mid)//拆分 
{
	IT it=s.lower_bound(Node(mid));
	if(it!=s.end()&&it->l==mid) return it;
	it--;
	int L=it->l,R=it->r;
	int V=it->v;
	s.erase(it);
	s.insert(Node(L,mid-1,V));
	return s.insert(Node(mid,R,V)).first;
}
int assign(int l,int r,int v)
{
	int ret=0;
	IT L=split(l),R=split(r+1);
	for(IT it=L;it!=R;++it)
	{
		if(it->v!=v) ret+=(it->r-it->l+1);
	}
	s.erase(L,R);
	s.insert(Node(l,r,v));
	return ret;
}

void dfs1(int rt,int f)
{
	size[rt]=1;
	fa[rt]=f;
	for(int i=head[rt];i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==f) continue;
		dfs1(v,rt);
		size[rt]+=size[v];
		if(size[son[rt]]<size[v]) son[rt]=v;
	}
}
void dfs2(int rt)
{
	int v=son[rt];
	if(v)
	{
		seg[v]=++seg[0];
		top[v]=top[rt];
		dfs2(v);
	}
	for(int i=head[rt];i;i=edge[i].next)
	{
		v=edge[i].to;
		if(v==fa[rt]||v==son[rt]) continue;
		seg[v]=++seg[0];
		top[v]=v;
		dfs2(v);
	}
}

int modify_edge(int x)
{
	int fx=top[x],ret=0;
	while(fx!=1)
	{
		ret+=assign(seg[fx],seg[x],1);
		x=fa[fx];fx=top[x];
	}
	ret+=assign(seg[1],seg[x],1);
	return ret;
}
int cut_tree(int rt)
{
	return assign(seg[rt],seg[rt]+size[rt]-1,0);
}

int main()
{
	read(n);
	for(int i=1;i<n;++i)
	{
		int x;
		read(x);
		add_edge(x+1,i+1);
	}
	s.insert(Node(1,n+1,0));
	top[1]=seg[0]=seg[1]=1;
	dfs1(1,1);
	dfs2(1);
	
	read(m);
	
	while(m--)
	{
		char sss[101];int x;
		scanf("%s",sss);
		read(x);++x;
		if(sss[0]=='i') printf("%d\n",modify_edge(x));
		else if(sss[0]=='u') printf("%d\n",cut_tree(x));
	}
	return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...