CSP S2020 函式呼叫(洛谷民間資料)

2022-05-09 10:21:10 字數 2453 閱讀 4175

傳送門

其實除了第一題,剩下幾道出的都挺不錯的,至於賽制的改變我也不知道會帶來了什麼影響,畢竟我已經不是oi選手了(似乎又搞起了acm)。

廢話不多說。這道題思維難度真的挺大的,想了半天也沒想出正解,題解也是看了好長一段時間才懂,感覺自己原來沒這麼菜啊……

所以這裡先隆重推出一篇題解:ak dream的[csp2020-函式呼叫]

我們把函式呼叫關係的圖建出來,容易看出這是乙個dag,而且只有出度為1的點是功能一或功能二。

首先考慮如果只有功能二,那麼我們只要記錄每乙個函式(下文就叫做節點好了)被呼叫的次數,最後在dag上dp就行了,複雜度是線性的。

現在新增了功能一,就得換一種思路:每乙個加法操作執行的次數都相當於他後面的所有乘法操作之積。

所以我們倒著來處理執行的函式。

記mul[u]表示呼叫節點\(u\)後執行的所有乘法操作之積。這個開始在dag上預處理一下就行:功能一和功能三的mul初始化為1,功能二的mul剛開始就是他要乘的值。然後倒著在dag上跑一遍就能算出所有mul[i]了。

處理完mul後,倒著執行函式的時候,首先要有乙個累乘值\(m\),表示從最後有多少個乘法操作,那麼如果呼叫了函式\(u\),\(u\)包含的所有加法操作都至少要執行\(m\)次,因此我們給\(u\)的標記加\(m\),然後\(m\)要再乘以mul[u]。

為什麼說是至少執行\(m\)次呢?因為\(u\)內部可能是加法乘法操作混合的。因此下傳標記的時候也要按\(u\)自己呼叫函式的順序下傳:對於\(u\)呼叫的乙個節點\(v\),他要乘的值除了\(m\)還有\(v\)之前\(u\)呼叫的節點的mul,乘上然後下傳給\(v\)即可。

這樣最後對於每乙個數,除了乘上\(m\),再加上所有加法操作乘以他們的標記就好啦。

最後下傳標記的時候應該是每乙個節點倒著訪問他的每一條出邊,但是因為鏈前存圖本身就是倒著的,因此剛好符合了這一點。

寫完題解後感覺不是很難,話說這就是思維題的魅力嘛,難的不會,會的不難。

#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define enter puts("")

#define space putchar(' ')

#define mem(a, x) memset(a, x, sizeof(a))

#define in inline

#define fore(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)

typedef long long ll;

typedef double db;

const int inf = 0x3f3f3f3f;

const db eps = 1e-8;

const ll mod = 998244353;

const int maxn = 1e5 + 5;

in ll read()

in void write(ll x)

in void myfile()

int n, m, q, a[maxn], q[maxn];

ll mul = 1;

struct node

t[maxn];

struct edge

e[maxn * 10];

int head[maxn], du[maxn], ecnt = -1;

in void addedge(int x, int y)

; head[x] = ecnt;

++du[y];

}in ll add(ll a, ll b)

int d[maxn], cnt = 0;

in void topo()

}in void calc_mul()

}in void calc_sum() }}

int main()

else if(op == 2) t[i].mul = read();

else

}q = read();

for(int i = 1; i <= q; ++i) q[i] = read();

topo();

calc_mul();

for(int i = q; i; --i)

calc_sum();

for(int i = 1; i <= n; ++i) a[i] = 1ll * a[i] * mul % mod;

for(int i = 1; i <= m; ++i) if(t[i].p)

a[t[i].p] = add(a[t[i].p], t[i].v * t[i].sum % mod);

for(int i = 1; i <= n; ++i) write(a[i]), space; enter;

return 0;

}

CSP S 2020初賽遊記

早上七點起床,初賽就在學校裡面考,先去食堂吃了個早飯,高糖的那種畢竟據說考試前攝入醣類能提高智商 然後去機房溜達了一下,膜拜了眾多大神,就是沒有拜夏農爸爸 然後我那個題就選錯了 看了一會兒之後被叫下去考試,考室裡面有很多小朋友,每乙個看起來都很厲害的亞子,我就有點慌,有要考差的預感。卷子發下來了,看...

CSP S 2020初賽遊記

考試前對自己做了一大堆心理輔導,在群裡面也分享了一些東西,用來釋放自己的壓力 然後就懷著必勝的信念打初賽了,可是迅速就從必勝變成了必敗 那是誰?yzhang 那是誰?pmt 那是誰?duyi 那是誰?b6e0 那是誰?名字真的忘了,反正是去年的js省隊選手 這不炸了呀,怎麼考 旁邊坐著一堆巨佬,我不...

CSP S2020 浙江 遊記

今天是 2020 年 10 月 9 日,距離初賽還有兩天 算兩天嗎,完整的應該只有一天多了 原本對於比賽還是沒什麼感覺的,每天做做題,水水文章,感覺時間就這麼過去了,但是最近犇犇裡各種各樣的遊記都已經冒出來了,驚醒了我 原來今年的聯賽已經向我逼近了嗎?說實話,剛進入高中,感覺新的競賽模式的學習讓我挺...