QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#553210#7563. Fun on Treeucup-team1231#ML 6ms55144kbC++175.0kb2024-09-08 10:43:082024-09-08 10:43:08

Judging History

你现在查看的是最新测评结果

  • [2024-09-08 10:43:08]
  • 评测
  • 测评结果:ML
  • 用时:6ms
  • 内存:55144kb
  • [2024-09-08 10:43:08]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define SZ 234567
template<class T>
void cmax(T&a,T b) {if(a<b)a=b;}
int n,q,fa[SZ];
ll a[SZ],fe[SZ];
int sz[SZ],son[SZ],top[SZ],fc[SZ];
vector<int> fcc[SZ];
ll dd[SZ];
void dfs(int x) {
    dd[x]=dd[fa[x]]+fe[x];
    sz[x]=1;
    for(auto s:fcc[x]) {
        dfs(s);
        sz[x]+=sz[s];
        if(sz[s]>sz[son[x]]) son[x]=s;
    }
    // cerr<<x<<":"<<son[x]<<"+\n";
}
int D=0,fx[SZ],dw[SZ];
void dfs2(int x,int t) {
    top[x]=t; fc[x]=++D; dw[t]=x;
    if(son[x]) dfs2(son[x],t);
    for(auto s:fcc[x]) if(s!=son[x]) dfs2(s,s);
    fx[x]=D;
}
#define pb push_back
#define sz(t) int((t).size())
typedef pair<ll,int> pll;
#define fi first
#define se second
pll operator + (pll a,ll b) {
    return pll(a.fi+b,a.se);
}
pll operator - (pll a,ll b) {
    return pll(a.fi-b,a.se);
}
#define PS 4100000
pll pool1[PS+PS],*p1=pool1;
ll pool2[PS+PS],*p2=pool2;
struct Seg {
int M=262144;
bool built=0;
vector<pair<int,pll>> es;
int mi=2e9,mx=-2e9,N;
pll*seg;
ll*tg;
// vector<pll> seg;
// vector<ll> tg;
void build() {
    if(built) return;
    built=1;
    N=mx-mi+1;
    if(N<=0) {N=0; return;}
    M=1;
    while(M<n+1) M<<=1;
    seg=p1; p1+=M+M+1;
    tg=p2; p2+=M+M+1;
    // seg.resize(M+M+1);
    // tg.resize(M+M+1);
    for(int i=0;i<=M+M;++i) seg[i]=pll(-4e18,0);
    for(auto e:es) cmax(seg[e.fi-mi+M+1],e.se);
    for(int i=M-1;i>=0;--i) seg[i]=max(seg[i+i],seg[i+i+1]);
}
void edt(int x,pll p) {
    assert(!built);
    es.pb(make_pair(x,p));
    mx=max(mx,x);
    mi=min(mi,x);
}
pll qry(int x,int l,int r,int ql,int qr) {
    if(ql>qr||r<ql||qr<l) return pll(-4e18,0);
    if(ql<=l&&r<=qr) {
        return seg[x]+tg[x];
    }
    int m=(l+r)>>1;
    pll aa=max(qry(x+x,l,m,ql,qr),qry(x+x+1,m+1,r,ql,qr));
    return aa+tg[x];
}
void add(int x,int l,int r,int ql,int qr,ll v,ll s=-1) {
    if(ql>qr||r<ql||qr<l) return;
    if(ql<=l&&r<=qr) {
        tg[x]+=v;
        if(s!=-1) seg[x].se=s;
        return;
    }
    int m=(l+r)>>1;
    add(x+x,l,m,ql,qr,v,s);
    add(x+x+1,m+1,r,ql,qr,v,s);
    seg[x]=max(seg[x+x]+tg[x+x],seg[x+x+1]+tg[x+x+1]);
}
pll qry(int l,int r) {
    l=l-mi+1; r=r-mi+1;
    if(l>r) return pll(-4e18,0);
    build();
    assert(l>=1&&r<=N);
    return qry(1,0,M-1,l,r);
}
pll qry() {
    return qry(mi,mx);
}
void add(int l,int r,ll v,ll s=-1) {
    l=l-mi+1; r=r-mi+1;
    if(l>r) return;
    build();
    assert(l>=1&&r<=N);
    add(1,0,M-1,l,r,v,s);
}
}Sub,Top,sA,sB,A[233333],B[233333];
pll sAc[SZ],sBc[SZ];
void edt(int x,int v) {
    Sub.add(fc[x],fx[x],v);
    // cerr<<D<<":"<<n<<" "<<fc[x]<<"~"<<fx[x]<<" "<<Top.mi<<"~"<<Top.mx<<"\n";
    Top.add(fc[x],fx[x],v); // add v if your top is in this subtree
    if(x!=top[x]) {
        sA.add(fc[x],fc[dw[x]],v);
        sB.add(fc[x],fc[dw[x]],v);
    }
    for(int t=x;t;t=fa[top[t]]) {
        if(t==x) continue;
        int f=fc[t];
        ll dt;
        dt=-sAc[f].fi;
        A[f].add(fc[x],fx[x],v);
        dt+=(sAc[f]=A[f].qry()).fi;
        sA.add(f,f,dt,sAc[f].se);
        dt=-sBc[f].fi;
        B[f].add(fc[x],fx[x],v);
        dt+=(sBc[f]=B[f].qry()).fi;
        sB.add(f,f,dt,sBc[f].se);
        // sB.add(f,f,dt);
    }
}
#define ed fx
pll qry(int x) {
    pll ans = Sub.qry(fc[x],ed[x])-dd[x];
    ll td=0;
    for(int t=x;t;t=fa[top[t]]) {
        ll chainbuff = Top.qry(fc[top[t]],fc[top[t]]).fi;
        int L=fc[top[t]],M=fc[t],R=fc[dw[t]];
        // cerr<<t<<"->"<<top[t]<<"  "<<fa[top[t]]<<"+\n";
        // cerr<<sA.qry(1,1).fi<<" "<<dd[t]-dd[top[t]]<<" "<<chainbuff<<"+\n";
        if(L<M) ans=max(ans,sA.qry(L,M-1)+dd[t]-dd[top[t]]+td+chainbuff);
        if(M<R) ans=max(ans,sB.qry(M+1,R)-(dd[t]-dd[top[t]])+td+chainbuff);
        td+=dd[t]-dd[fa[top[t]]];
    }
    return ans;
}
int main() {
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i) scanf("%lld",a+i),a[i]*=-1;
    for(int i=2;i<=n;++i)
        scanf("%d%lld",fa+i,fe+i),
        fcc[fa[i]].pb(i);
    dfs(1); dfs2(1,1);
    for(int i=1;i<=n;++i) Top.edt(i,pll(0,-i));
    for(int i=1;i<=n;++i) {
        Sub.edt(fc[i],pll(dd[i]+a[i],-i));
        for(int t=i;t;t=fa[top[t]]) {
            ll B=dd[i]-dd[t],A=dd[t]-dd[top[t]];
            ::A[fc[t]].edt(fc[i],pll(B-A+a[i],-i));
            ::B[fc[t]].edt(fc[i],pll(B+A+a[i],-i));
        }
    }
    for(int i=1;i<=n;++i) {
        sA.edt(fc[i],sAc[fc[i]]=A[fc[i]].qry());
        sB.edt(fc[i],sBc[fc[i]]=B[fc[i]].qry());
    }
    while(q--) {
        int x,y,v;
        scanf("%d%d%d",&x,&y,&v);
        edt(y,-v);
        auto q=qry(x);
        printf("%lld %lld\n",-q.se,q.fi);
    }
}
/*
6 1
1 1 4 5 1 4
1 5
2 0
3 2
4 1
5 6
2 2 66


6 6
1 1 4 5 1 4
1 5
2 0
3 2
4 1
5 6
3 2 -100000
1 2 100000
1 1 0
2 2 66
3 1 5
4 4 -3

5 3
-10 0 2 -4 8
1 7
1 1
2 2
2 -2
4 3 0
2 5 0
5 2 0


5 6
-10 0 2 -4 8
1 7
1 1
2 2
2 -2
1 1 100
2 1 -100
1 1 0
4 3 10
2 5 3
5 2 2

6 3
0 0 0 0 0 0
1 10
1 10
1 -100
4 10
4 11
1 1 0
4 1 0
1 4 1000
*/

详细

Test #1:

score: 100
Accepted
time: 3ms
memory: 55144kb

input:

6 6
1 1 4 5 1 4
1 5
2 0
3 2
4 1
5 6
3 2 -100000
1 2 100000
1 1 0
2 2 66
3 1 5
4 4 -3

output:

6 100005
6 10
6 10
1 4
1 -1
1 1

result:

ok 6 lines

Test #2:

score: 0
Accepted
time: 4ms
memory: 51068kb

input:

5 6
-10 0 2 -4 8
1 7
1 1
2 2
2 -2
1 1 100
2 1 -100
1 1 0
4 3 10
2 5 3
5 2 2

output:

4 -87
1 17
4 13
1 19
1 17
1 15

result:

ok 6 lines

Test #3:

score: 0
Accepted
time: 6ms
memory: 55124kb

input:

6 3
0 0 0 0 0 0
1 10
1 10
1 -100
4 10
4 11
1 1 0
4 1 0
1 4 1000

output:

2 10
6 11
2 10

result:

ok 3 lines

Test #4:

score: 0
Accepted
time: 4ms
memory: 50928kb

input:

2 0
1 1
1 3

output:


result:

ok 0 lines

Test #5:

score: -100
Memory Limit Exceeded

input:

200000 200000
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 ...

output:


result: