输入格式
输入文件的第 11 行包含 11 个正整数 nn,表示软件包的总数。软件包从 00 开始编号。随后一行包含 n-1n−1 个整数,相邻整数之间用单个空格隔开,分别表示1,2,3,…,n−2,n−1 号软件包依赖的软件包的编号。接下来一行包含一个正整数 qq,表示询问的总数。之后 qq 行,每行一个询问。询问分为两种:install x:表示安装软件包 xxuninstall x:表示卸载软件包 xx
你需要维护每个软件包的安装状态,一开始所有的软件包都处于未安装状态。对于每个操作,你需要输出这步操作会改变多少个软件包的安装状态,随后应用这个操作(即改变你维护的安装状态)。
输出格式
输出文件包括 qq 行。输出文件的第 ii 行输出一个整数,为第 ii 步操作中改变安装状态的软件包数。
数据范围和约定
对于所有数据,n ≤100000, q≤100000。
样例输入
7
0 0 0 1 1 5
5
install 5
install 6
uninstall 1
install 4
uninstall 0
样例输出
3
1
3
2
3
#include<iostream>
#include<cstring>
using namespace std;
int n, q;
int unstep=0;
int a[100000];//存储编号为n的软件包所依赖的软件包编号
int b[100000];
int install(int num,int step);
int uninstall(int num,int shangyige);
int main()
{
a[0]=0;//0号软件包没有依赖
b[0]=0;
cin >> n;
//读取依赖
for (int i = 1; i<n; i++)
{
cin>>a[i];
b[i]=a[i];
}
cin >> q;
for (int i = 0; i<q; i++)
{
char p[15];
cin >> p;
if (strcmp(p, "install")==0)
{
//cout<<1;
int ins;
cin>>ins;
cout<<install(ins,0)<<endl;
}
else if(strcmp(p, "uninstall")==0)
{
//cout<<2;
int unins;
cin>>unins;
unstep=0;
cout<<uninstall(unins,a[unins])<<endl;
}
}
return 0;
}
int install(int num,int step)
{
//-1代表已安装
if(a[num]!=-1)
{
int kk=a[num];
a[num]=-1;
install(kk,step+1);
}
else
{
a[num]=-1;
return step;
}
}
int uninstall(int num,int shangyige)
{
//-1代表已安装
//shangyige 为安装状态-1 或 其他为未安装
//如果编号为num的软件已安装
if(shangyige==-1)
{
if(unstep==0)
{
unstep++;
a[num]=b[num];
}
//如果有依赖为num且已install,删除依赖为num的软件
for(int i=0;i<n;i++)
{
if(a[i]!=-1)
continue;
else if( (b[i]==num) )
{
int kk = a[i];
unstep++;
a[i]=num;
uninstall(i,kk);
}
}
return unstep;
}
else
return 0;
}