题目
题解思路
一开始想着先dfs一遍处理乘法除法的值。
第二次dfs的时候标记特判。
Wa了。
其实不用这么麻烦,我们只需从头扫到根节点,将有潜力变成乘法或者除法里的数分开进行。
当运算到加减法的时候可以将之前的有潜力的就一定不可能再变成乘除法了,将加减的数变成新的有潜力的数。
乘除法类似。
除法记得逆元
这样属实巧妙。
还是说我写太少树的题了。
还是太菜了。
AC代码
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f ;
const int mod = 1e9 + 7 ;
const int N = 100010 ;
long long a[N] ;
long long ans[N] ;
vector <int> head[N] ;
char fh[N] ;
int n ;
int falg = 0 ;
long long qsm(long long a, long long b)
{
long long ans = 1, t = a;
while(b)
{
if (b & 1) ans = ans *t % mod;
t = t * t % mod;
b >>= 1;
}
return ans % mod;
}
long long ni(long long x )
{
return qsm(x,mod-2) ;
}
void dfs(int p , long long t1 , long long t2 )
{
ans[p] = (t1 + t2 )%mod ;
for (int i = 0 ; i < head[p].size() ; i++ )
{
int sp = head[p][i] ;
if ( fh[sp] == '+')
{
dfs(sp,(t1+t2+mod)%mod,a[sp]);
}else if (fh[sp] == '-' )
dfs(sp,(t1+t2+mod)%mod,(-a[sp]+mod)%mod);
else if ( fh[sp] == '*' )
{
dfs(sp,t1,t2*a[sp]%mod);
}else
dfs(sp,t1,t2*ni(a[sp])%mod);
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin >> n ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
for (int i = 1 ; i < n ; i++ )
{
int t1 ;
cin >> t1 ;
head[t1].push_back(i+1);
}
cin >> fh+2 ;
dfs(1,0,a[1]);
for (int i = 1 ; i <= n ; i++ )
cout << ans[i] << " " ;
cout << "\n" ;
return 0 ;
}