0分倍增的代码求调
查看原帖
0分倍增的代码求调
50506
qyzyq楼主2023/11/9 21:42

有哪位大佬来看看蒟蒻的倍增哪里写错了吗?样例过了,但是全部 WA,求助

#include<bits/stdc++.h>
#define int long long
#define ll long long
using namespace std;
const ll N=3e5+50,INF=1e18;
int n,m,a[N];
ll h[N],v[N];
vector<int> e[N];
ll fa[N][20],hp[N][20],cha[N][20][2];//1乘0加 
//wz i 表示从 wz 开始(不算 wz)的 2^i 个城池
//fa表示第 2^i 个城池是哪个
//hp表示攻占这 2^i 个城池至少要多少血
int dep[N],lg[N],ksm[N];
int ans[N],ans1[N],ttt;
ll zx(ll bc,ll cs)
{
	ll re=bc/cs;
	if(re*cs<bc) re++;
	return re;
}
void dfs1(int wz,int last)
{
	dep[wz]=dep[last]+1;
	cha[wz][0][1]=1;
	if(wz!=1)
	{
		fa[wz][0]=last;
		hp[wz][0]=h[last];
		cha[wz][0][a[last]]=v[last];
	}
	for(int i=1;i<=lg[dep[wz]-1];i++)//因为不包含 wz 
	{
		fa[wz][i]=fa[fa[wz][i-1]][i-1];
		hp[wz][i]=max(hp[wz][i-1],zx(hp[fa[wz][i-1]][i-1]-cha[wz][i-1][0],cha[wz][i-1][1]));
		cha[wz][i][1]=cha[wz][i-1][1]*cha[fa[wz][i-1]][i-1][1];
		cha[wz][i][0]=cha[wz][i-1][0]*cha[fa[wz][i-1]][i-1][1]+cha[fa[wz][i-1]][i-1][0];
	}
	for(int i=0;i<e[wz].size();i++)
		dfs1(e[wz][i],wz);
}
int dfs2(int wz,ll st)
{
	ttt=0;
	if(st<h[wz])
	{
		ans[wz]++;
		return ttt;
	}
	if(a[wz]==1) st*=v[wz];
	else st+=v[wz];
	ttt++;
	for(int i=lg[dep[wz]-1];i>=0;i--)
	{
		if(wz==1) break;
		if(st>=hp[wz][i]) st=st*cha[wz][i][1]+cha[wz][i][0],wz=fa[wz][i],ttt+=ksm[i];
	}
	ans[fa[wz][0]]++;
	return ttt;
}
signed main()
{
	int sr;
	scanf("%lld %lld",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld",&h[i]);
	for(int i=2;i<=n;i++)
	{
		scanf("%lld %lld %lld",&sr,&a[i],&v[i]);
		e[sr].push_back(i);
	}
	for(int i=1;i<=n;i++)
		lg[i]=lg[i-1]+((1ll<<lg[i-1])==i);
	lg[0]=-1;
	ksm[0]=1;
	for(int i=1;i<=20;i++)
	ksm[i]=ksm[i-1]*2;
	for(int i=1;i<=n;i++)
		lg[i]--;
	dfs1(1,0);
	ll s;
	for(int i=1;i<=m;i++)
	{
		scanf("%lld %lld",&s,&sr);
		ans1[i]=dfs2(sr,s);
	}
	for(int i=1;i<=n;i++)
		printf("%lld\n",ans[i]);
	for(int i=1;i<=m;i++)
		printf("%lld\n",ans1[i]);
	return 0;
}
2023/11/9 21:42
加载中...