P7895 的爆标做法
令
我们的思路是,当 del 操作删叶子,当
经过一些尝试,可以发现我们最多使用
我们先来证明一下
可以发现:
于是我们只需要一个能够在
令
我们直接对每条边计算是没法做的,因为边数太多了。所以一次查询距离我们要得到很多边的信息。
我们尝试使用每个点到根的距离进行计算(之后默认将
我们来证明一下这个东西。
对每条边考虑它被计算了几次。
定义
对于
对于一个非根结点
然后我们再对之前的式子进行转化,可以得到:
这说明了每条边的贡献恰好计算了
利用这个式子,我们只需要对
对于一个有 dis 操作就能够得到答案。
标算需要
而且并不需要用到 dfn 操作。
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int k=142,n,deg[5005];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;++i)cin>>deg[i];
while(1){
int t=0;
for(int i=2;i<=n;++i)if(deg[i]!=2)++t;
if(t<k){
LL ans=0;
for(int i=2;i<=n;++i)if(deg[i]!=2){
LL v=0;
cout<<"dis 1 "<<i<<endl;
cin>>v;
ans+=v*(2-deg[i]);
}
cout<<"! "<<ans<<endl;
break;
}else{
cout<<"del"<<endl;
--k;
cin>>n;
for(int i=1;i<=n;++i)cin>>deg[i];
}
}
return 0;
}