提出 #52901323


ソースコード 拡げる

// LUOGU_RID: 157303998
#include <iostream>
#include <cstdio>
#define ls (x << 1)
#define rs (x << 1 | 1)
#define mid ((l + r) >> 1)
#define int long long
using namespace std;

const int mod = 998244353;

struct matr
{
	int ma[3][3];
} uni,mat[200010];

int n,q;
int a[200010],A[200010],res[200010];
int to[200010],nxt[200010],head[200010],cnt;
int dfn[200010],siz[200010],son[200010],dfncnt,tp[200010],la[200010],dep[200010],fa[200010];
struct node
{
	int xl,xr;
	matr M;
} tree[800010];
int cnt0[200010],g[200010];

int ksm(int x,int y)
{
	int res = 1;
	while (y)
	{
		if (y & 1) res = res * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return res;
}

matr tms(matr x,matr y)
{
	matr re;
	for (int i = 1;i <= 2;i ++)
		for (int j = 1;j <= 2;j ++)
			re.ma[i][j] = 0;
	for (int i = 1;i <= 2;i ++)
		for (int j = 1;j <= 2;j ++)
			for (int k = 1;k <= 2;k ++)
				re.ma[i][j] = (re.ma[i][j] + x.ma[i][k] * y.ma[k][j] % mod) % mod;
	return re;
}

void pushup(int x)
{
	tree[x].M = tms(tree[rs].M,tree[ls].M);
}

void build(int x,int l,int r)
{
	tree[x].xl = l,tree[x].xr = r;
	if (l == r)
	{
		tree[x].M = mat[l];
		return ;
	}
	build(ls,l,mid),build(rs,mid + 1,r);
	pushup(x);
}

void upd(int x,int qx)
{
	int l = tree[x].xl,r = tree[x].xr;
	if (l == r)
	{
		tree[x].M = mat[l];
		return ;
	}
	if (qx <= mid) upd(ls,qx);
	else upd(rs,qx);
	pushup(x);
}

matr query(int x,int ql,int qr)
{
	int l = tree[x].xl,r = tree[x].xr;
	if (l >= ql && r <= qr) return tree[x].M;
	matr res = uni;
	if (mid < qr) res = query(rs,ql,qr);
	if (ql <= mid) res = tms(res,query(ls,ql,qr));
	return res;
}

void add(int x,int y)
{
	to[++ cnt] = y;
	nxt[cnt] = head[x];
	head[x] = cnt;
}

void dfs(int x)
{
	siz[x] = 1;
	for (int i = head[x];i;i = nxt[i])
	{
		int u = to[i];
		dep[u] = dep[x] + 1;
		fa[u] = x;
		dfs(u);
		siz[x] += siz[u];
		if (siz[u] > siz[son[x]]) son[x] = u;
	}
}

void dfss(int x,int topx)
{
	tp[x] = topx;
	dfn[x] = ++ dfncnt;
	if (!son[x])
	{
		la[topx] = x;
		mat[dfn[x]].ma[2][1] = a[x],mat[dfn[x]].ma[2][2] = 1;
		res[x] = a[x];
		return ;
	}
	g[x] = 1;
	dfss(son[x],topx);
	for (int i = head[x];i;i = nxt[i])
	{
		int u = to[i];
		if (u == son[x]) continue;
		dfss(u,u);
		g[x] = g[x] * (res[u] ? res[u] : 1) % mod;
		if (!res[u]) cnt0[x] ++;
	}
	A[x] = (cnt0[x] ? 0 : g[x]);
	mat[dfn[x]].ma[1][1] = A[x],mat[dfn[x]].ma[2][1] = a[x],mat[dfn[x]].ma[2][2] = 1;
	res[x] = (A[x] * res[son[x]] % mod + a[x]) % mod;
}

void upde(int x,int y,int k)
{
	mat[dfn[x]].ma[2][1] = (a[x] + k) % mod;
	while (tp[x] != tp[y])
	{
		if (dep[tp[x]] < dep[tp[y]]) swap(x,y);
		upd(1,dfn[x]);
		matr nw = query(1,dfn[tp[x]],dfn[la[tp[x]]]);
		cnt0[fa[tp[x]]] -= (res[tp[x]] == 0);
		g[fa[tp[x]]] = g[fa[tp[x]]] * ksm((res[tp[x]] ? res[tp[x]] : 1),mod - 2) % mod;
		cnt0[fa[tp[x]]] += (nw.ma[2][1] == 0);
		g[fa[tp[x]]] = g[fa[tp[x]]] * (nw.ma[2][1] ? nw.ma[2][1] : 1) % mod;
		if (!cnt0[fa[tp[x]]]) A[fa[tp[x]]] = g[fa[tp[x]]];
		else A[fa[tp[x]]] = 0;
		mat[dfn[fa[tp[x]]]].ma[1][1] = A[fa[tp[x]]];
		res[tp[x]] = nw.ma[2][1];
		x = fa[tp[x]];
	}
	if (dfn[x] > dfn[y]) swap(x,y);
	upd(1,dfn[y]);
}

signed main()
{
	A[0] = 1;
	scanf("%lld%lld",&n,&q);
	uni.ma[1][1] = uni.ma[2][2] = 1;
	for (int i = 2;i <= n;i ++)
	{
		int x;
		scanf("%lld",&x);
		add(x,i);
	}
	for (int i = 1;i <= n;i ++) scanf("%lld",a + i);
	dfs(1);
	dfss(1,1);
	build(1,1,n);
	while (q --)
	{
		int x,y;
		scanf("%lld%lld",&x,&y);
		upde(x,1,(y - a[x] + mod) % mod);
		a[x] = y;
		printf("%lld\n",query(1,1,dfn[la[1]]).ma[2][1]);
	}
}

提出情報

提出日時
問題 G - Hash on Tree
ユーザ RabbieWjy
言語 C++ 17 (gcc 12.2)
得点 650
コード長 3674 Byte
結果 AC
実行時間 2391 ms
メモリ 98744 KiB

コンパイルエラー

Main.cpp: In function ‘int main()’:
Main.cpp:165:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  165 |         scanf("%lld%lld",&n,&q);
      |         ~~~~~^~~~~~~~~~~~~~~~~~
Main.cpp:170:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  170 |                 scanf("%lld",&x);
      |                 ~~~~~^~~~~~~~~~~
Main.cpp:173:42: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  173 |         for (int i = 1;i <= n;i ++) scanf("%lld",a + i);
      |                                     ~~~~~^~~~~~~~~~~~~~
Main.cpp:180:22: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  180 |                 scanf("%lld%lld",&x,&y);
      |                 ~~~~~^~~~~~~~~~~~~~~~~~

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 650 / 650
結果
AC × 3
AC × 46
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 02_random_max_00.txt, 02_random_max_01.txt, 02_random_max_02.txt, 02_random_max_03.txt, 03_path_00.txt, 04_star_00.txt, 04_star_01.txt, 04_star_02.txt, 04_star_03.txt, 05_centipede_00.txt, 05_centipede_01.txt, 05_centipede_02.txt, 05_centipede_03.txt, 05_centipede_04.txt, 05_centipede_05.txt, 05_centipede_06.txt, 05_centipede_07.txt, 05_centipede_08.txt, 05_centipede_09.txt, 05_centipede_10.txt, 05_centipede_11.txt, 06_n-ary_00.txt, 06_n-ary_01.txt, 06_n-ary_02.txt, 06_n-ary_03.txt, 06_n-ary_04.txt, 06_n-ary_05.txt, 06_n-ary_06.txt, 06_n-ary_07.txt, 06_n-ary_08.txt, 06_n-ary_09.txt, 07_corner_00.txt, 08_hld_worst_complexity_00.txt, 08_hld_worst_complexity_01.txt, 08_hld_worst_complexity_02.txt, 08_hld_worst_complexity_03.txt, 08_hld_worst_complexity_04.txt, 09_corner_2_00.txt, 09_corner_2_01.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 1 ms 3808 KiB
00_sample_01.txt AC 1 ms 3856 KiB
00_sample_02.txt AC 1 ms 3912 KiB
01_random_00.txt AC 1484 ms 81924 KiB
01_random_01.txt AC 1497 ms 80484 KiB
01_random_02.txt AC 1434 ms 78080 KiB
01_random_03.txt AC 1049 ms 25348 KiB
02_random_max_00.txt AC 1528 ms 86276 KiB
02_random_max_01.txt AC 1545 ms 86336 KiB
02_random_max_02.txt AC 1507 ms 86372 KiB
02_random_max_03.txt AC 1528 ms 86288 KiB
03_path_00.txt AC 336 ms 98744 KiB
04_star_00.txt AC 647 ms 75204 KiB
04_star_01.txt AC 665 ms 78476 KiB
04_star_02.txt AC 677 ms 80976 KiB
04_star_03.txt AC 674 ms 78660 KiB
05_centipede_00.txt AC 547 ms 92512 KiB
05_centipede_01.txt AC 559 ms 93040 KiB
05_centipede_02.txt AC 616 ms 89592 KiB
05_centipede_03.txt AC 618 ms 89384 KiB
05_centipede_04.txt AC 668 ms 81672 KiB
05_centipede_05.txt AC 695 ms 80300 KiB
05_centipede_06.txt AC 678 ms 81388 KiB
05_centipede_07.txt AC 688 ms 81672 KiB
05_centipede_08.txt AC 656 ms 91544 KiB
05_centipede_09.txt AC 657 ms 91604 KiB
05_centipede_10.txt AC 745 ms 90168 KiB
05_centipede_11.txt AC 740 ms 90144 KiB
06_n-ary_00.txt AC 2346 ms 82272 KiB
06_n-ary_01.txt AC 2076 ms 81116 KiB
06_n-ary_02.txt AC 1792 ms 80008 KiB
06_n-ary_03.txt AC 1466 ms 79328 KiB
06_n-ary_04.txt AC 1059 ms 78580 KiB
06_n-ary_05.txt AC 865 ms 78420 KiB
06_n-ary_06.txt AC 829 ms 78420 KiB
06_n-ary_07.txt AC 653 ms 78664 KiB
06_n-ary_08.txt AC 2391 ms 80680 KiB
06_n-ary_09.txt AC 2349 ms 80976 KiB
07_corner_00.txt AC 617 ms 94132 KiB
08_hld_worst_complexity_00.txt AC 2247 ms 86332 KiB
08_hld_worst_complexity_01.txt AC 2193 ms 86340 KiB
08_hld_worst_complexity_02.txt AC 2019 ms 86316 KiB
08_hld_worst_complexity_03.txt AC 1739 ms 86736 KiB
08_hld_worst_complexity_04.txt AC 1345 ms 87200 KiB
09_corner_2_00.txt AC 352 ms 8348 KiB
09_corner_2_01.txt AC 570 ms 78444 KiB