社区讨论

孩子主席树两个#8 #10 TLE了,有没有好心人看看如何卡常 QAQ

P7768「CGOI-1」收税参与者 1已保存回复 0

讨论操作

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

当前回复
0 条
当前快照
1 份
快照标识符
@ltcznshs
此快照首次捕获于
2024/03/04 21:40
2 年前
此快照最后确认于
2024/03/05 13:23
2 年前
查看原帖
评测记录:https://www.luogu.com.cn/record/149366006 Code:
CPP
// P7768
#include <bits/stdc++.h>
using std::cin,std::cout,std::vector,std::string;
#define endl "\n"

template <typename T>
inline void read(T &x) {
    x=0; bool f=false; char c=getchar();
    while(c<'0'||c>'9'){ if(c=='-') f=true; c=getchar(); }
    while(c>='0'&&c<='9'){ x=(x<<1)+(x<<3)+(c^48); c=getchar(); }
    if(f) x=-x;
}
template <typename T, typename ...Args>
inline void read(T &tmp,Args &...tmps){ read(tmp); read(tmps...); }

struct node{ int L,R,val; };
int cnt=0;

std::vector<node>tree(1);

int update(int pre,int pl,int pr,int x,int v) {
    int rt=++cnt;
    tree.emplace_back(tree[pre]); tree[rt].val^=v;
    if(int mid=pl+pr>>1; pl<pr){
        if(x<=mid) tree[rt].L=update(tree[pre].L,pl,mid,x,v);
        else tree[rt].R=update(tree[pre].R,mid+1,pr,x,v);
    }
    return rt;
}

int query(int l,int r,int pl,int pr,int _L,int _R) {
    // l,r 均为树的编号, pl,pr 当前节点的范围, _L,_R 询问区间
    if(_L<=pl&&pr<=_R) return tree[l].val^tree[r].val;
    int res=0, mid=pl+pr>>1;
    if(_L<=mid) res^=query(tree[l].L,tree[r].L,pl,mid,_L,_R);
    if(_R>mid) res^=query(tree[l].R,tree[r].R,mid+1,pr,_L,_R);
    return res;
}

int main()
{
    int n,m; read(n,m);
    vector<int>aa(n+1);
    vector<vector<int>>adj(n+1);
    for(int i=1;i<=n;++i) read(aa[i]);
    for(int u=2;u<=n;++u){
        int v; read(v);
        adj[u].emplace_back(v); adj[v].emplace_back(u);
    }

    vector<int>dep(n+1,0), L(n+1), R(n+1), id(n+1);
    int tot=0;
    auto dfs0=[&](auto self,int now,int pre)->void{
        dep[now]=dep[pre]+1;
        L[now]=++tot; id[tot]=now;
        for(auto nxt:adj[now]){
            if(nxt!=pre) self(self,nxt,now);
        }
        R[now]=tot;
    };
    dfs0(dfs0,1,0);
    auto max_dep=*std::max_element(dep.begin(),dep.end());

    vector<int>root(n+1);
    for(int i=1;i<=n;++i) // 按照dfn序建立主席树
        root[i]=update(root[i-1],1,max_dep,dep[id[i]],aa[id[i]]);
    while(m--){
        int x,h; read(x,h);
        int res=query(root[L[x]-1],root[R[x]],1,max_dep,dep[x],std::min(dep[x]+h,max_dep));
        printf("%.3f\n",res*0.001);
    }
    return 0;
}

回复

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

正在加载回复...