社区讨论

如果你一直RE找不到原因

SP11470TTM - To the moon参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lvzaf8rf
此快照首次捕获于
2024/05/09 21:32
2 年前
此快照最后确认于
2024/05/10 10:22
2 年前
查看原帖
可能是因为没有使用标记永久化
RE代码:
CPP
// P7424
#include <bits/stdc++.h>
using std::cin,std::cout,std::vector;
// using std::endl;
#define endl "\n"
typedef long long ll;
typedef std::pair<int,int> PII;
typedef std::pair<ll,ll> PLL;
typedef std::tuple<int,int,int> T3I;
typedef std::tuple<int,int,int,int> T4I;

const int N=1e5+3;

struct Node{
    int ls,rs;
    ll sum;
}tree[N<<5];

int tot=0, root[N];

#define mid (rtL+rtR>>1)
int build(int rtL, int rtR, vector<int>&aa) {
    int rt=++tot;
    if(rtL==rtR){
        tree[rt].sum=aa[rtL];
    }
    else{
        tree[rt].ls=build(rtL,mid,aa);
        tree[rt].rs=build(mid+1,rtR,aa);
        tree[rt].sum=tree[tree[rt].ls].sum+tree[tree[rt].rs].sum;
    }
    return rt;
}

int update(int pre, int rtL, int rtR, int L, int R, ll d) {
    int rt=++tot;
    tree[rt]=tree[pre];
    tree[rt].sum+=d*(std::min(R,rtR)-std::max(L,rtL)+1);
    if(rtL<rtR){
        if(L<=mid) tree[rt].ls=update(tree[pre].ls,rtL,mid,L,R,d);
        if(R>mid) tree[rt].rs=update(tree[pre].rs,mid+1,rtR,L,R,d);
    }
    return rt;
}

ll query(int rt, int rtL, int rtR, int L, int R) {
    if(L<=rtL&&rtR<=R) return tree[rt].sum;
    ll ans=0;
    if(L<=mid) ans+=query(tree[rt].ls,rtL,mid,L,R);
    if(R>mid) ans+=query(tree[rt].rs,mid+1,rtR,L,R);
    return ans;
}
#undef mid

int main()
{
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int n,m; cin>>n>>m;
    vector<int>aa(n+1);
    for(int i=1;i<=n;++i) cin>>aa[i];
    int now=0; // now 当前的时间戳
    root[0]=build(1,n,aa);

    while(m--){
        char opt; int l,r,t,d; cin>>opt;
        switch(opt){
        case 'C':
            cin>>l>>r>>d;
            root[now+1]=update(root[now],1,n,l,r,d);
            ++now;
            break;
        case 'Q':
            cin>>l>>r;
            cout<<query(root[now],1,n,l,r)<<endl;
            break;
        case 'H':
            cin>>l>>r>>t;
            cout<<query(root[t],1,n,l,r)<<endl;
            break;
        case 'B':
            cin>>now;
            break;
        }
    }
    return 0;
}
AC代码:
CPP
struct Node{
    int ls,rs;
    ll sum,add;
}tree[N*200];

int tot=0, root[N];
ll aa[N];

#define mid (rtL+rtR>>1)
int build(int rtL, int rtR) {
    int rt=++tot;
    if(rtL==rtR){
        tree[rt].sum=aa[rtL];
    }
    else{
        tree[rt].ls=build(rtL,mid);
        tree[rt].rs=build(mid+1,rtR);
        tree[rt].sum=tree[tree[rt].ls].sum+tree[tree[rt].rs].sum;
    }
    return rt;
}

int update(int pre, int rtL, int rtR, int L, int R, ll d) {
    if(L>rtR||R<rtL) return 0;
    int rt=++tot;
    tree[rt]=tree[pre];
    tree[rt].sum+=d*(std::min(R,rtR)-std::max(L,rtL)+1);
    if(L<=rtL&&rtR<=R) tree[rt].add+=d;
    else if(rtL<rtR){
        if(L<=mid) tree[rt].ls=update(tree[pre].ls,rtL,mid,L,R,d);
        if(R>mid) tree[rt].rs=update(tree[pre].rs,mid+1,rtR,L,R,d);
    }
    return rt;
}
两份代码主要的区别是 第一份代码每次修改直接修改到最底端,第二份使用了标记永久化
虽然我也不知道为什么SPOJ的错误提示是 RE 而不是 WA,但是采用标记永久化就AC了

回复

0 条回复,欢迎继续交流。

正在加载回复...