CSP2020 S 解題報告(Updating)

2022-02-22 13:08:19 字數 2710 閱讀 7951

(waiting updating)

題目大意:

這個題大概就是說每種動物編號的二進位制位中是 \(1\) 的位對應了這種動物所需要的飼料之一,讓你去求在當前飼料供給條件下,還能多飼養多少動物。

仔細想一下會發現,其實並沒有必要去維護所謂的飼料種類 \(c\) 。這取決於題面中一條很重要的性質,就是保證 \(q_i\) 互不相同。

這樣的話就只會出現乙個二進位制位對應多種飼料,而不會出現一種飼料對應多個二進位制位的情況,這樣的話就可以考慮用 \(p_i\) 來維護所需要的飼料種數。

考慮相同的二進位制位對飼料種類的貢獻是重疊的,所以就可以把所有的已有的動物編號或起來,然後對於給定的每乙個 \(p_i\) ,看一下對應的二進位制位是否為 \(1\) 。

如果為 \(1\) , 那編號二進位制此位為 \(1\) 的動物就可以新增進來飼養, 若為 \(0\) 就會導致飼料種類發生變化,不可以飼養。

這樣最後的結果就是 \(2^ - n\) , \(cnt\) 為會導致飼料種類發生變化的二進位制位個數。

最後,這個題有兩個坑點:一是對於相同的 \(p_i\) ,只能統計一次;二是當 \(n = 0\) 且 \(k = 64\) 時,答案會爆 \(unsigned long long\) , 需要特判一下。

#include#include#include#include#include#define maxn 1000005

typedef unsigned long long ull;

int n, m, c, k, cnt;

int p[maxn], q[maxn];

ull a[maxn], al;

std::mapm;

template inline void read(i &x) while(ch < '0' || ch > '9');

do while(ch >= '0' && ch <= '9');

x *= f; return;

}template inline void write(i x)

if(x > 9) write(x / 10);

putchar( x % 10 + '0');

}int main()

由於考場上持續剛t1,導致t3t4基本沒怎麼看/kk

出考場以後發現有個線段樹的暴力做法還是挺簡單的(但是就是沒空寫了)

導致我白白丟了70pts……

下面進入正題:

首先考慮怎麼去處理乘法和加法操作:

想一想可以發現,對於乙個操作序列 $ a_i + p , a_i \times q $ , 可以將其轉化為 $ a_i \times q , a_i + p \times q $ 。

由此可知,可以把先加後乘的操作序列修改為先乘後加的操作序列, 且修改後加法操作相當於進行了 $ q $ 次。

然後考慮操作的呼叫。由題目中的約束條件可知,所有操作呼叫構成一張dag。因此,考慮建立乙個超級原點, 這個點連向所有初始呼叫的操作,這樣就構成了一棵以 0 為原點的操作樹。

考慮按 「左 -> 右 -> 中」 對該樹進行遍歷, 更新出執行到該點時全域性乘上的值, 也就相當於執行次數。

考慮操作樹上的每乙個點時, 連向該點的邊應當全部被處理完, 即入度為 0 , 所以考慮用拓撲排序來解決這個問題。

當拓撲到乙個點時,該點的執行次數相當於該點的父節點的執行次數 + 該點父節點呼叫的操作當中在該操作之後的操作的執行次數。

這樣做的理由就是對於每個點而言,它的影響因子是在它之後的所有點(之前的處理到該點時已經確定了)。

所以這樣整體思路就有了。具體細節看**:

#include#include#include#include#include#include#define maxn 100005

#define mod 998244353

typedef long long ll;

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

std::vectorg[maxn];

ll mul[maxn], add[maxn];

int in[maxn], t[maxn];

bool vis[maxn];

struct reservation ipt[maxn];

template inline void read(i &x) while(ch < '0' || ch > '9');

do while(ch >= '0' && ch <= '9');

x *= f; return;

}void dfs(int k)

for(int i = 0; i < g[k].size(); ++i)

return;

}void toposort(void)

} return;

}int main()

} read(q);

for(int i = 1, ue; i <= q; ++i)

ipt[0].opt = 3;

dfs(0);

toposort();

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

for(int i = 1; i <= n; ++i) printf("%d ", a[i]);

puts("");

return 0;

}

(waiting updating)

CSP 2020 S 蒟蒻的遊記 (洛谷同步)

t1 毒瘤模擬 我 if 計算函式 打 調了2小時 樣例wa了 心態炸了 t2.我沒學過如何計算並儲存乙個數的每乙個二進位制位 但是,蒟蒻也是個s選手嘛 於是,推了乙個不是很靠譜的式子 過了乙個樣例,另乙個少了一點值 而且,我考後恍然大悟,我陣列怕炸,只開了60分的大小 我完全可以開大點的 祝所有人...

CSP2019 JX 散步 解題報告

csp2019 jx 散步 有乙個長度為 l 的環 2 le l le 10 9 環上有 n 個人,m 個出口 1 le n,m le 2 times 10 5 規定第乙個出口的位置為 0 並將 到第乙個出口的距離 定義為 從順時針方向走到第乙個路口所走的路程 每個人有兩個屬性 t i,x i 分別...

CSP2019 劃分 解題報告

csp2019 劃分 有乙個長度為 n 的序列 a i n le 4 times 10 7 求 sum a i 2 sum a i 2 dots sum 1 a i 2 的最小值.結論 上述式子能取到最小值,當且僅當最後一塊 即 sum 1 a i 取到了最小值.證明 暫時不會.那我們就 dp 保證...