社区讨论

求调代码

P11824[湖北省选模拟 2025] 团队协作 / team参与者 1已保存回复 1

讨论操作

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

当前回复
1 条
当前快照
1 份
快照标识符
@mks7kn4j
此快照首次捕获于
2026/01/24 19:10
上个月
此快照最后确认于
2026/02/11 02:30
4 周前
查看原帖
不需要通过,不需要考虑常数和空间复杂度,只要能调过样例就行
用转置原理做的,转置之前的问题用线段树合并做的,测试过应该是对的,但是转置了之后过不去样例
我直接把所有对变量的修改存起来的,已经调了很久了,可能我对转置原理还有理解不对的地方
CPP
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pii pair<ll,ll>
#define fi first
#define se second
#define i128 __int128
#define ALL(x) x.begin(),x.end()
#define popcount(x) __builtin_popcountll(x)
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#endif
using namespace std;
const int INF=1e18;
const int N=100005;
const int MOD1=1e9+7,MOD2=998244353;
const int MOD=MOD1;
template<class T>
using must_int=enable_if_t<is_integral<T>::value,int>;
template<int P>
struct modint{
    static constexpr signed mod=P;
    unsigned v;
    modint():v(0){}
    template<class T,must_int<T> =0>
    modint(T x){x%=mod;v=x<0?x+mod:x;}
    modint operator+()const{return *this;}
    modint operator-()const{modint res;res.v=v?mod-v:0;return res;}
    friend int raw(const modint&self){return self.v;}
    friend ostream& operator<<(ostream& os,const modint&self){return os<<self.v;}
    modint& operator+=(modint rhs){v+=rhs.v;if(v>=mod)v-=mod;return *this;}
    modint& operator-=(modint rhs){v-=rhs.v;if(v>=mod)v+=mod;return *this;}
    modint& operator*=(modint rhs){v=1ull*v*rhs.v%mod;return *this;}
    modint& operator/=(modint rhs){return *this*=qpow(rhs,mod-2);}
    template<class T,must_int<T> =0>
    friend modint qpow(modint a,T b){
        modint r=1;
        for(;b;b>>=1,a*=a)if(b&1)r*=a;
        return r;
    }
    friend modint operator+(modint lhs,modint rhs){return lhs+=rhs;}
    friend modint operator+(modint lhs,int rhs){return lhs+=(modint)rhs;}
    friend modint operator+(int lhs,modint rhs){return (modint)lhs+=rhs;}
    friend modint operator-(modint lhs,modint rhs){return lhs-=rhs;}
    friend modint operator-(modint lhs,int rhs){return lhs-=(modint)rhs;}
    friend modint operator-(int lhs,modint rhs){return (modint)lhs-=rhs;}
    friend modint operator*(modint lhs,modint rhs){return lhs*=rhs;}
    friend modint operator*(modint lhs,int rhs){return lhs*=(modint)rhs;}
    friend modint operator*(int lhs,modint rhs){return (modint)lhs*=rhs;}
    friend modint operator/(modint lhs,modint rhs){return lhs/=rhs;}
    friend modint operator/(modint lhs,int rhs){return lhs/=(modint)rhs;}
    friend modint operator/(int lhs,modint rhs){return (modint)lhs/=rhs;}
    bool operator==(modint rhs)const{return v==rhs.v;}
    bool operator!=(modint rhs)const{return v!=rhs.v;}
    explicit operator unsigned()const{return v;}
};
template <int P>
string to_string(modint<P> x) { return std::to_string(x.v); }
using mint = modint<MOD2>;

int n,m;
vector<int> G[N];
int a[N];
int b[N];
int now=0;
struct OP_{
    mint *x,*y;
    mint k;
    int op;//op=0:x*=k op=1:x+=k*y op=2:x=y op=3:clear
};
vector<OP_> OP;
struct Pair{
    mint cnt,val;
    Pair operator += (Pair &y){
        cnt+=y.cnt;
        // val+=y.val;
        OP.push_back({&val,&y.val,1,1});
        return *this;
    }
    Pair operator -= (Pair &y){
        cnt-=y.cnt;
        // val-=y.val;
        OP.push_back({&val,&y.val,-1,1});
        return *this;
    }
    Pair operator *= (Pair &y){
        //val*=y.cnt;
        OP.push_back({&val,0,y.cnt,0});
        //val+=cnt*y.val;
        OP.push_back({&val,&y.val,cnt,1});
        cnt*=y.cnt;
        return *this;
    }
    Pair operator = (Pair &y){
        cnt=y.cnt;
        //val=y.val;
        OP.push_back({&val,&y.val,0,2});
        return *this;
    }
    void clear(){
        OP.push_back({&val,0,0,3});
    }
    bool operator == (Pair y){
        return cnt==y.cnt&&val==y.val;
    }
};
Pair tmp_,tmp2_;
struct segtree{
    struct Tag{
        Pair a,b,c,d;
        Tag operator *= (Tag &y){
            // res.a=a*y.a+b*y.c;
            // res.b=a*y.b+b*y.d;
            // res.c=c*y.a+d*y.c;
            // res.d=c*y.b+d*y.d;
            tmp_=b;
            tmp2_=a;
            a*=y.a;
            tmp_*=y.c;
            a+=tmp_;

            b*=y.d;
            tmp2_*=y.b;
            b+=tmp2_;

            tmp_=d;
            tmp2_=c;
            c*=y.a;
            tmp_*=y.c;
            c+=tmp_;

            d*=y.d;
            tmp2_*=y.b;
            d+=tmp2_;

            return *this;
        }
    }tag[40*N],tmp1,tmp2,tmp3;
    Tag tag2[N];
    struct Info{
        Pair x,y;//0/1
        Info operator *= (Tag &y_){
            // Info res;
            // res.x=x*y_.a+y*y_.c;
            // res.y=x*y_.b+y*y_.d;
            // return res;
            tmp_=y;
            tmp2_=x;
            x*=y_.a;
            tmp_*=y_.c;
            x+=tmp_;
            y*=y_.d;
            tmp2_*=y_.b;
            y+=tmp2_;
            return *this;
        }
    }tmpinfo1;
    struct node{
        int ls,rs;
        Info val;
    }tr[40*N];
    int tot;
    int newnode(){
        ++tot;


        // tr[tot].val.x=tr[tot].val.y={1,0};
        // tag[tot]={{1,0},{0,0},{0,0},{1,0}};
        tr[tot].val.x.cnt=tr[tot].val.y.cnt=1;
        
        //tr[tot].val.x.val=tr[tot].val.y.val=0;

        tag[tot].a.cnt=tag[tot].d.cnt=1;
        //tag[tot].b.cnt=tag[tot].c.cnt=0;
        //tag[tot]={{1,0},{0,0},{0,0},{1,0}};
        tr[tot].ls=tr[tot].rs=0;
        return tot;
    }
    void pushdown(int p){
        if(tag[p].a==(Pair){1,0}&&tag[p].b==(Pair){0,0}
        &&tag[p].c==(Pair){0,0}&&tag[p].d==(Pair){1,0}){
            return;
        }
        if(!tr[p].ls){
            tr[p].ls=newnode();
        }
        if(!tr[p].rs){
            tr[p].rs=newnode();
        }
        tr[tr[p].ls].val*=tag[p];
        tr[tr[p].rs].val*=tag[p];
        tag[tr[p].ls]*=tag[p];
        tag[tr[p].rs]*=tag[p];
        debug(1);
        //tag[p]={{1,0},{0,0},{0,0},{1,0}};
        tag[p].a.clear();
        tag[p].b.clear();
        tag[p].c.clear();
        tag[p].d.clear();
        tag[p].a.cnt=tag[p].d.cnt=1;
        tag[p].b.cnt=tag[p].c.cnt=0;
        tag[p].b.val=tag[p].c.val=tag[p].a.val=tag[p].d.val=0;
    }
    int modify(int p,int l,int r,int L,int R,Tag &c){//1乘
        if(L>R)return p;
        if(!p)p=newnode();
        if(l>=L&&r<=R){
            tr[p].val*=c;
            tag[p]*=c;
            return p;
        }
        pushdown(p);
        int mid=(l+r)/2;
        if(mid>=L)tr[p].ls=modify(tr[p].ls,l,mid,L,R,c);
        if(mid<R)tr[p].rs=modify(tr[p].rs,mid+1,r,L,R,c);
        return p;
    }
    int merge(int px,int py,int l,int r){//对位乘
        if(!px||!py){
            return px+py;
        }
        if(l==r){
            tr[px].val.x*=tr[py].val.x;
            tr[px].val.y*=tr[py].val.y;
            return px;
        }
        if(!tr[px].ls&&!tr[px].rs){
            tmp_=tag[px].a;
            tmp_+=tag[px].c;

            tmp2_=tag[px].b;
            tmp2_+=tag[px].d;
            auto tmp=(Tag){tmp_,{0,0},{0,0},tmp2_};
            tr[py].val*=tmp;
            tag[py]*=tmp;
            return py;
        }
        if(!tr[py].ls&&!tr[py].rs){
            tmp_=tag[py].a;
            tmp_+=tag[py].c;

            tmp2_=tag[py].b;
            tmp2_+=tag[py].d;
            auto tmp=(Tag){tmp_,{0,0},{0,0},tmp2_};
            tr[px].val*=tmp;
            tag[px]*=tmp;
            return px;
        }
        pushdown(px);
        pushdown(py);
        int mid=(l+r)/2;
        tr[px].ls=merge(tr[px].ls,tr[py].ls,l,mid);
        tr[px].rs=merge(tr[px].rs,tr[py].rs,mid+1,r);
        return px;
    }
    Pair &query(int p,int l,int r,int x){
        if(!p){
            tmp_.cnt=1;
            tmp_.val=0;
            return tmp_;
        }
        if(l==r){
            debug(l,tr[p].val.x.cnt);
            //debug(tr[p].val.x.cnt,tr[p].val.x.val);
            return tr[p].val.x;
        }
        if(!tr[p].ls&&!tr[p].rs){
            debug(l);
            tmp_=tag[p].b;
            tmp_+=tag[p].d;
            return tmp_;
        }
        pushdown(p);
        int mid=(l+r)/2;
        if(mid>=x)return query(tr[p].ls,l,mid,x);
        else return query(tr[p].rs,mid+1,r,x);
    }
}T;
int rt[N];
void dfs(int u,int fa){

    rt[u]=T.modify(rt[u],1,n,1,a[u]-1,T.tmp1);
    //debug(T.tag2[u].d.cnt,T.tag2[u].d.val);
    rt[u]=T.modify(rt[u],1,n,a[u],n,T.tag2[u]);
    
    for(auto v:G[u]){
        if(v==fa)continue;
        dfs(v,u);
        rt[u]=T.merge(rt[u],rt[v],1,n);
    }
    
    
    rt[u]=T.modify(rt[u],1,n,1,n,T.tmp2);
    
    rt[u]=T.modify(rt[u],1,n,1,n,T.tmp3);
}
vector<int> vec_[N];
Pair ans[N];
int b_[N];
void solve_(){
    cin>>n;
    T.tmp1.a.cnt=1;
    T.tmp2.b.cnt=T.tmp2.c.cnt=1;
    T.tmp3.a.cnt=T.tmp3.c.cnt=T.tmp3.d.cnt=1;
    for(int i=1;i<=n;i++){
        T.tag2[i].a.cnt=T.tag2[i].d.cnt=1;
    }
    for(int i=2;i<=n;i++){
        int x;
        cin>>x;
        G[i].push_back(x);
        G[x].push_back(i);
    }
    vector<int> vec;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        vec.push_back(a[i]);
    }
    sort(ALL(vec));
    vec.erase(unique(ALL(vec)),vec.end());
    m=vec.size();
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(ALL(vec),a[i])-vec.begin()+1;
        b_[i]=a[i];
        vec_[a[i]].push_back(i);
    }
    int tot=0;
    for(int i=1;i<=n;i++){
        for(auto j:vec_[i]){
            a[j]=++tot;
        }
    }
    for(int i=1;i<=n;i++){
        b[a[i]]=b_[i];
    }
    dfs(1,0);
    for(int i=1;i<=n;i++){
        ans[i]=T.query(rt[1],1,n,i);
    }
    for(int i=n;i>=2;i--){
        ans[i]-=ans[i-1];
    }
    for(int i=1;i<=n;i++){
        ans[i].val=vec[b[i]-1];
        debug(ans[i].val);
    }
    reverse(ALL(OP));
    int cnt=0;
    for(auto i:OP){
        //debug(i.op);
        if(i.op==0){
            (*i.x)*=i.k;
        }else if(i.op==1){
            (*i.y)+=i.k*(*i.x);
        }else if(i.op==2){
            (*i.y)+=(*i.x);
            (*i.x)=0;
        }else{
            (*i.x)=0;
        }
        cnt++;
        // if(cnt==2||cnt==1){
        //     for(int j=1;j<=n;j++){
        //         debug(j,ans[j].val);
        //     }
        // }
    }
    // for(int i=1;i<=n;i++){
    //     debug(ans[i].val);
    // }
    for(int i=1;i<=n;i++){
        cout<<T.tag2[i].d.val<<" ";
    }
}
signed main(){
    // freopen("team.in","r",stdin);
    // freopen("team.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int testcase,multitest=0;
    if(multitest)cin>>testcase;
    else testcase=1;
    while(testcase--){
        solve_();
    }
    return 0;
}

回复

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

正在加载回复...