题解:JudgeOnline/upload/201604/Solution-4458.rar By jinlifu1999
超级钢琴...都已经成经典了
本来想打树链剖分和ST表的,后来看题解发现倍增更好打,膜打树链的Evan
题目后跟个题解链接是SMG
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<ll,int> abcd;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(ll &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
int n,m,L,R,M;
ll ans;
int depth[500005];
ll s[500005];
int fat[500005][25];
abcd st[500005][25];
inline void build_fat(){
for (int k=1;k<=20;k++)
for (int i=1;i<=n;i++)
fat[i][k]=fat[fat[i][k-1]][k-1];
}
inline int Fat(int u,int d){
for (int k=20;k>=0;k--)
if ((d>>k)&1)
u=fat[u][k];
return u;
}
inline void build_st(){
for (int i=0;i<=n;i++)
st[i][0]=abcd(s[i],i);
for (int k=1;k<=20;k++)
for (int i=0;i<=n;i++)
st[i][k]=min(st[i][k-1],st[fat[i][k-1]][k-1]);
}
inline abcd Query(int u,int d){
abcd ret(1LL<<60,0);
for (int k=20;k>=0;k--)
if ((d>>k)&1)
ret=min(ret,st[u][k]),u=fat[u][k];
return ret;
}
struct node{
int u,l,r,m;
ll val;
node () { }
node (int u,int l,int r):u(u),l(l),r(r) { }
void calc(){
int f=Fat(u,l+1);
abcd ret=Query(f,r-l);
val=s[u]-ret.first;
m=depth[u]-depth[ret.second];
}
bool operator < (const node &B) const{
return val<B.val;
}
};
priority_queue<node> Q;
int main()
{
int l,r;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n);
for (int i=1;i<=n;i++)
read(fat[i][0]);
for (int i=1;i<=n;i++)
read(s[i]);
read(M); read(L); read(R);
for (int i=1;i<=n;i++)
s[i]+=s[fat[i][0]],depth[i]=depth[fat[i][0]]+1;
build_fat();
build_st();
node tmp;
for (int i=1;i<=n;i++)
{
if (L>depth[i]) continue;
l=L-1; r=min(R,depth[i]);
if (l<r)
{
tmp=node(i,l,r);
tmp.calc();
Q.push(tmp);
}
}
for (int i=1;i<=M;i++)
{
if (Q.empty()) return printf("-01\n"),0;
tmp=Q.top(); Q.pop();
ans+=tmp.val;
int m=tmp.m,l=tmp.l,r=tmp.r,u=tmp.u;
if (l<m-1)
{
tmp=node(u,l,m-1);
tmp.calc();
Q.push(tmp);
}
if (m<r)
{
tmp=node(u,m,r);
tmp.calc();
Q.push(tmp);
}
}
printf("%lld\n",ans);
return 0;
}