Description

大家应该都读过题。

Solution

赛后变摩托。

我们对每一个操作 \(3\) 连边建图,然后可以知道只是一个 \(\texttt{DAG}\)。

考虑操作 \(2\),我们只需要最后计算即可。

现在来看加法操作。我们设我们当前的操作为 \(a_{p}\leftarrow a_{p}+v\),后面一共有 \(k\) 个乘法操作,我们设为分别让序列整体乘上 \(b_{1,2,\cdots,k}\)。那么 \(a_{p}\leftarrow a_{p}+v\) 一共会对最后的 \(a_{p}\) 产生 \(v\times\prod_{i=1}^{k}b_{i}\) 的贡献。

于是我们可以把操作离线下来,倒着来处理。

那么最后来考虑操作 \(3\),我们来看操作 \(3\) 连出的图。

对于图上的每一个节点我们维护一个值,表示执行后会带来的系数。

那么和操作 \(1\) 类似的,我们对整张图进行拓扑,然后倒着处理,处理出每个节点的操作的加法计算了多少次,然后传播(指所有相邻节点)到加法操作的节点。

最后处理原序列即可。

(代码从 \(\texttt{Vim}\) 里面复制出来可能缩进有问题)

#include <queue>
#include <cstdio>
#define mod ( 998244353 ) using namespace std;
typedef long long LL; const int MAXN = 1e6 + 5; template<typename _T>
void read( _T &x ){
x = 0; char c = getchar(); _T f = 1;
while( c < '0' || c > '9' ){ if( c == '-' ) f = -1; c = getchar(); }
while( c >= '0' && c <= '9' ){ x = ( x << 3 ) + ( x << 1 ) + ( c & 15 ); c = getchar(); }
x *= f;
} template<typename _T>
void write( _T x ){
if( x < 0 ){ putchar( '-' ); x = -x; }
if( x > 9 ) write( x / 10 );
putchar( x % 10 + '0' );
} struct starS{
int to, nxt;
starS( int T = 0, int N = 0 ){ to = T; nxt = N; }
} as[MAXN * 2]; struct operateS{
int Tp, pos;
LL add, mul, sum;
operateS( int T = 0, int P = 0, LL A = 0, LL M = 0, LL S = 0 ){ Tp = T; pos = P; add = A; mul = M; sum = S; }
} opS[MAXN]; int N, M, Q;
int totE, totT;
int A[MAXN], topS[MAXN], degS[MAXN], firS[MAXN], queS[MAXN]; void pushEdge( int u, int v ){ as[++ totE] = starS( v, firS[u] ); firS[u] = totE; } void TopSort( ){
queue<int> align;
for( int i = 1; i <= M; ++ i ){
if( ! degS[i] ) align.push( i );
}
while( ! align.empty( ) ){
int u = align.front( ); align.pop( );
topS[++ totT] = u;
for( int i = firS[u]; i; i = as[i].nxt ){
int v = as[i].to; degS[v] --;
if( ! degS[v] ) align.push( v );
}
}
} int main( ){
read( N );
for( int i = 1; i <= N; ++ i ) read( A[i] );
read( M );
for( int i = 1; i <= M; ++ i ){
read( opS[i].Tp );
if( opS[i].Tp == 1 ){
read( opS[i].pos ); read( opS[i].add );
opS[i].mul = 1;
}
else if( opS[i].Tp == 2 ) {
read( opS[i].mul );
opS[i].add = opS[i].mul;
}
else{
read( opS[i].pos );
opS[i].mul = 1;
for( int j = 1, to; j <= opS[i].pos; ++ j ){ read( to ); pushEdge( i, to ); degS[to] ++; }
}
}
TopSort( );
for( int i = M; i; -- i ){
int u = topS[i];
for( int j = firS[u]; j; j = as[j].nxt ){
int v = as[j].to;
opS[u].mul = ( LL )opS[u].mul * opS[v].mul % mod;
}
}
read( Q ); int now = 1;
for( int i = 1; i <= Q; ++ i ) read( queS[i] );
for( int i = Q; i; -- i ){ opS[queS[i]].sum = ( ( LL )opS[queS[i]].sum + now ) % mod; now = ( LL )now * opS[queS[i]].mul % mod; }
for( int i = 1; i <= M; ++ i ){
int u = topS[i], now = 1;
for( int j = firS[u]; j; j = as[j].nxt ){
int v = as[j].to;
opS[v].sum = ( ( LL )opS[u].sum * now % mod + opS[v].sum ) % mod;
now = ( LL )now * opS[v].mul % mod;
}
}
for( int i = 1; i <= N; ++ i ) A[i] = ( LL )A[i] * now % mod;
for( int i = 1; i <= M; ++ i ){
if( opS[i].Tp == 1 ) A[opS[i].pos] = ( A[opS[i].pos] + ( LL )opS[i].add * opS[i].sum % mod ) % mod;
}
for( int i = 1; i <= N; ++ i ) write( A[i] ), putchar( ' ' );
return 0;
}

Solution -「CSP-S 2020」函数调用的更多相关文章

  1. Solution -「多校联训」排水系统

    \(\mathcal{Description}\)   Link.   在 NOIP 2020 A 的基础上,每条边赋权值 \(a_i\),随机恰好一条边断掉,第 \(i\) 条段的概率正比于 \(a ...

  2. Note/Solution -「洛谷 P5158」「模板」多项式快速插值

    \(\mathcal{Description}\)   Link.   给定 \(n\) 个点 \((x_i,y_i)\),求一个不超过 \(n-1\) 次的多项式 \(f(x)\),使得 \(f(x ...

  3. Solution -「洛谷 P4198」楼房重建

    \(\mathcal{Description}\)   Link.   给定点集 \(\{P_n\}\),\(P_i=(i,h_i)\),\(m\) 次修改,每次修改某个 \(h_i\),在每次修改后 ...

  4. Solution -「洛谷 P6577」「模板」二分图最大权完美匹配

    \(\mathcal{Description}\)   Link.   给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...

  5. Solution -「多校联训」I Love Random

    \(\mathcal{Description}\)   给定排列 \(\{p_n\}\),可以在其上进行若干次操作,每次选取 \([l,r]\),把其中所有元素变为原区间最小值,求能够得到的所有不同序 ...

  6. Solution -「多校联训」签到题

    \(\mathcal{Description}\)   Link.   给定二分图 \(G=(X\cup Y,E)\),求对于边的一个染色 \(f:E\rightarrow\{1,2,\dots,c\ ...

  7. Solution -「多校联训」朝鲜时蔬

    \(\mathcal{Description}\)   Link.   破案了,朝鲜时蔬 = 超现实树!(指写得像那什么一样的题面.   对于整数集 \(X\),定义其 好子集 为满足 \(Y\sub ...

  8. Solution -「多校联训」消失的运算符

    \(\mathcal{Description}\)   Link.   给定长度为 \(n\) 的合法表达式序列 \(s\),其中数字仅有一位正数,运算符仅有 - 作为占位.求将其中恰好 \(k\) ...

  9. Solution -「多校联训」假人

    \(\mathcal{Description}\)   Link.   一种物品有 长度 和 权值 两种属性,现给定 \(n\) 组物品,第 \(i\) 组有 \(k_i\) 个,分别为 \((1,a ...

  10. Solution -「多校联训」古老的序列问题

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_n\}\),和 \(q\) 次形如 \([L,R]\) 的询问,每次回答 \[\sum_{[l,r]\su ...

随机推荐

  1. THM武器化

    Weaponization thm:https://tryhackme.com/room/weaponization 武器化 了解和探索常见的红队武器化技术.您将学习使用业内常见的方法构建自定义有效载 ...

  2. Java 写一个线程安全的单例模式(饱汉/饿汉)

    饿汉单例 public class Singleton { private static Singleton singleton = new Singleton(); private Singleto ...

  3. HCL实验:1.两台PC通过交换机ping通

    实验整体的拓扑图 进行交换机配置 配置好PC的ip netmask gatework 接口管理为启用状态 开启SW1 连接的端口 (一般来说是默认打开的,但有时候会自动关闭,很烦,所以最好加上这步) ...

  4. 我用numpy实现了VIT,手写vision transformer, 可在树莓派上运行,在hugging face上训练模型保存参数成numpy格式,纯numpy实现

    先复制一点知乎上的内容 按照上面的流程图,一个ViT block可以分为以下几个步骤 (1) patch embedding:例如输入图片大小为224x224,将图片分为固定大小的patch,patc ...

  5. 【Python】爬虫-Xpath

    Xpath 文章参考:https://www.cnblogs.com/mxjhaima/p/13775844.html#案例 安装 pip install lxml 引用 from lxml impo ...

  6. Go的语言特性有哪些

    摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 本文主要通过值传递和指针.字符串.数组.切片.集合.面向 ...

  7. git:gitignore常用配置

    配置 在项目文件中添加.gitignore文件 .DS_Store node_modules /dist

  8. 整理不错的opencv博客

    https://me.csdn.net/column/u013095718 更全的博客: https://blog.csdn.net/zhmxy555/column/info/opencv-tutor ...

  9. [kafka]常见术语

    前言 kafka属于分布式的消息引擎系统,主要功能是提供一套完备的消息发布与订阅解决方案. 消息和批次 kafka 的数据单元被称为消息.消息由字节数组组成,对kafka来说,消息里的数据没有特殊的格 ...

  10. 深入浅出 Typescript

    TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(ES6 教程). TypeScript 由微软开发的自由和开源的编程语言. TypeScript 设计 ...