0
点赞
收藏
分享

微信扫一扫

「JOISC 2022 Day3」洒水器

灯火南山 2022-04-06 阅读 32
算法

题目大意

给你一棵树,每个点有一个点权 h i h_i hi,修改操作:把距离 x x x小于等于 d d d的点的点权乘上 w w w,对 L L L取模, L L L在修改和查询前给出,查询某一个点的点权

题解

一开始看错题了,没发现 d ≤ 40 d\le 40 d40,由于 d d d很小,考虑有关 d d d的做法,我们不妨把修改全部用一种标记来表示,设 t a g x , y tag_{x,y} tagx,y表示在 x x x子树中距离 y y y的点的点权需要乘上 t a g x , y tag_{x,y} tagx,y,只用这种标记能否不重不漏的覆盖所有修改的点呢,答案是可行的,比如说有一个修改 x , d , w x,d,w x,d,w,可以把 x x x d d d级祖先都找出来,记为 f a fa fa,对于它们都这样打上标记 t a g f a , d − d i s ( f a , x ) ∗ = w , t a g f a , d − d i s ( f a , x ) − 1 ∗ = w tag_{fa,d-dis(fa,x)}*=w,tag_{fa,d-dis(fa,x)-1}*=w tagfa,ddis(fa,x)=w,tagfa,ddis(fa,x)1=w,不难发现这样就能覆盖所有需要修改的点,并且不会修改多次

code

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
#define gc() (fp==fq&&(fq=(fp=fr)+fread(fr,1,1<<20,stdin))==fp?EOF:*fp++)
char fr[1<<21],*fp,*fq;
void read(int &res)
{
	res=0;char ch=gc();
	while(ch<'0'||ch>'9') ch=gc();
	while('0'<=ch&&ch<='9') res=(res<<1)+(res<<3)+(ch^48),ch=gc();
}
void read(ll &res)
{
	res=0;char ch=gc();
	while(ch<'0'||ch>'9') ch=gc();
	while('0'<=ch&&ch<='9') res=(res<<1)+(res<<3)+(ch^48),ch=gc();
}
void write(ll res)
{
	if(res>=10) write(res/10),putchar('0'+res%10);
	else putchar('0'+res);
}
const int N=2e5+1000,B=40;
int n,q,fa[N+10],st[N+10],tot;ll l,h[N+10],tag[B+10][N+10];
struct edge
{
	int to,last;
}e[N<<1|1];
void add(int a,int b)
{
	e[++tot].to=b;
	e[tot].last=st[a];
	st[a]=tot;
}
void dfs(int u)
{
	for(int i=st[u],v;i!=0;i=e[i].last)
	{
		v=e[i].to;
		if(v==fa[u]) continue;
		fa[v]=u,dfs(v);
	}
}
void pushtag(int u,int d,ll k)
{
	if(d<0) return;
	if(d!=0) tag[d-1][u]*=k,tag[d-1][u]%=l;
	tag[d][u]*=k,tag[d][u]%=l;
	pushtag(fa[u],d-1,k);
}
ll querymul(int u,int d)
{
	if(d>40) return 1;
	return querymul(fa[u],d+1)*tag[d][u]%l;
}
int main()
{
	read(n),read(l);
	for(int i=1,a,b;i<n;i++) read(a),read(b),add(a,b),add(b,a);
	dfs(1);
	for(int i=1;i<=n;i++) read(h[i]);
	for(int i=0;i<=n;i++) for(int j=0;j<=B;j++) tag[j][i]=1;
	read(q);
	for(int t,x,d,w;q--;)
	{
		read(t),read(x);
		if(t==1) read(d),read(w),pushtag(x,d,w);
		else write(h[x]*querymul(x,0)%l),putchar('\n');
	}
	return 0;
}
举报

相关推荐

Day3

Python Day3

QT DAY3

Qt(day3)

Leetcode Day3

PAT DAY3

JS DAY3

0 条评论