社区讨论
孩子主席树两个#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 条回复,欢迎继续交流。
正在加载回复...