社区讨论
求为何我的代码会随机TLE
P6329【模板】点分树 / 震波参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lwj1vmyx
- 此快照首次捕获于
- 2024/05/23 17:28 2 年前
- 此快照最后确认于
- 2024/05/23 20:19 2 年前
如下代码可以得到很多种不同的分数。
CPP/*
Luogu name: Symbolize
Luogu uid: 672793
*/
#include<bits/stdc++.h>
//#define int long long
#define pii pair<int,int>
#define x first
#define y second
#define rep1(i,l,r) for(register int i=l;i<=r;++i)
#define rep2(i,l,r) for(register int i=l;i>=r;--i)
#define rep3(i,x,y,z) for(register int i=x[y];~i;i=z[i])
#define rep4(i,x) for(auto i:x)
#define debug() puts("----------")
const int N=1e5+10;
const int M=5e6+10;
const int inf=0x3f3f3f3f3f3f3f3f;
using namespace std;
int n,m,a[N],h[N],e[N<<1],ne[N<<1],idx,last,sz[N],Max[N],root,siz,Fa[N],dep[N],f[N][21];
bool vis[N];
struct Segment_Tree
{
int root[N],idx;
struct node
{
int l,r;
int sum;
}tr[M];
void push_up(int p){tr[p].sum=tr[tr[p].l].sum+tr[tr[p].r].sum;}
void update(int &p,int l,int r,int x,int k)
{
if(!p) p=++idx;
if(l==r)
{
tr[p].sum+=k;
return;
}
int mid=l+r>>1;
if(x<=mid) update(tr[p].l,l,mid,x,k);
else update(tr[p].r,mid+1,r,x,k);
push_up(p);
return;
}
int query(int p,int l,int r,int pl,int pr)
{
int ans=0;
if(!p) return 0;
if(pl<=l&&pr>=r) return tr[p].sum;
int mid=l+r>>1;
if(pl<=mid) ans+=query(tr[p].l,l,mid,pl,pr);
if(pr>mid) ans+=query(tr[p].r,mid+1,r,pl,pr);
return ans;
}
}seg1,seg2;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
void add(int x,int y)
{
e[idx]=y;
ne[idx]=h[x];
h[x]=idx++;
return;
}
void Dfs(int x,int fa)
{
f[x][0]=fa;
dep[x]=dep[fa]+1;
rep3(i,h,x,ne)
{
int to=e[i];
if(to==fa) continue;
Dfs(to,x);
}
return;
}
void init()
{
rep1(j,1,20) rep1(i,1,n) f[i][j]=f[f[i][j-1]][j-1];
return;
}
void plc(int &x,int k)
{
int kase=0;
while(k)
{
if(k&1) x=f[x][kase];
++kase;
k>>=1;
}
return;
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
plc(x,dep[x]-dep[y]);
if(x==y) return x;
rep2(i,20,0)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
void find_root(int x,int fa)
{
sz[x]=1;
Max[x]=0;
rep3(i,h,x,ne)
{
int to=e[i];
if(to==fa||vis[to]) continue;
find_root(to,x);
sz[x]+=sz[to];
Max[x]=max(Max[x],sz[to]);
}
Max[x]=max(Max[x],siz-sz[x]);
if(Max[x]<Max[root]) root=x;
return;
}
void dfs(int x)
{
vis[x]=1;
rep3(i,h,x,ne)
{
int to=e[i];
if(vis[to]) continue;
Max[0]=inf;
root=0;
siz=sz[to];
find_root(to,0);
Fa[root]=x;
dfs(root);
}
return;
}
int getdist(int x,int y){return dep[x]+dep[y]-2*dep[LCA(x,y)];}
void update(int x,int k)
{
int now=x;
while(now)
{
seg1.update(seg1.root[now],0,n-1,getdist(x,now),k);
if(Fa[now]) seg2.update(seg2.root[now],0,n-1,getdist(x,Fa[now]),k);
now=Fa[now];
}
return;
}
int query(int x,int k)
{
int now=x,son=0,ans=0;
while(now)
{
if(getdist(x,now)<=k)
{
ans+=seg1.query(seg1.root[now],0,n-1,0,k-getdist(x,now));
if(son) ans-=seg2.query(seg2.root[son],0,n-1,0,k-getdist(x,now));
}
son=now;
now=Fa[now];
}
return ans;
}
signed main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
memset(h,-1,sizeof h);
n=read();
m=read();
rep1(i,1,n) a[i]=read();
rep1(i,1,n-1)
{
int u=read();
int v=read();
add(u,v);
add(v,u);
}
Dfs(1,0);
init();
Max[0]=inf;
root=0;
siz=n;
find_root(1,0);
dfs(root);
rep1(i,1,n) update(i,a[i]);
while(m--)
{
int opt=read();
int x=read()^last;
int k=read()^last;
if(opt==0)
{
last=query(x,k);
cout<<last<<endl;
}
if(opt==1)
{
update(x,k-a[x]);
a[x]=k;
}
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...