提出 #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 |
| 結果 |
|
|
| セット名 |
テストケース |
| 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 |