Problem C 多執行緒 解題報告

2022-04-29 23:27:09 字數 1836 閱讀 5577

多執行緒是一種常見的加速手段,利用多個執行緒同時處理不同的任務可以一定程度上減少總耗時,達到提高效率的目的。然而,多個執行緒間的執行順序是完全不可控的,這常常會導致一些意料之外的問題。

乙個簡單的例子,如果三個執行緒分別輸出a,b,c, 你同時啟動這三個執行緒,最終的輸出可能是acb也可能是cba等等。更極端的例子,如果兩個執行緒分別輸出ab和ab,你甚至可能看到類似aabb和aabb的輸出。

當你拿到一串輸出而他們屬於多個執行緒的時候,反推出每個執行緒的輸出是一件非常麻煩的事情(甚至有時候完全不可能),很不幸,接下來你的任務就是這樣一件麻煩事。

【題意描述】

現在有兩個執行緒同時在輸出數列,執行緒a輸出乙個單調遞增數列,而執行緒b輸出乙個單調遞減數列。

距離來說,如果執行緒a輸出的是11,33,55,而執行緒b輸出的是44,22,那麼你可能看到以下的結果:

11 33 55 44 22

44 22 11 33 55

11 44 33 22 55

我們假設單個數的輸出是不會被打斷的(這個性質往往稱為「原子操作」),你不必擔心兩個數被同時輸出從而混合成乙個新的數。換言之,如果a輸出x個數而b輸出y個數,你最後一定會得到這x+y個數,只是順序不確定。

特別的,某個執行緒的輸出可能是空,你需要考慮到這一點。

現在你得到了最終的輸出,你需要反推出哪些數來自於執行緒a而哪些數來自於執行緒b。由於可能有多種情況,我們只要求你輸出方案數對1000000007取模的結果。

第一行乙個正整數t,表示測試資料組數。

接下來t行,每行描述一組測試資料:

第乙個整數n,表示最終的輸出包含n個整數

接下來n個整數ci,表示最終的輸出。

這些整數兩兩不同。

共t行,每行乙個整數,表示可能的情況數。

特別的,如果無解,你需要輸出乙個0。

對於100%的資料,1<=t<=10。

對於20%的資料,n<=20。

對於50%的資料,n<=1000。

對於80%的資料,n<=50000。

對於100%的資料,0<=n<=500000。

對於100%的資料,ci的絕對值不超過2000000000,且同一組資料內ci兩兩不同。

正解在我這種菜的人來說簡直不可做,我大概也說不清楚...

談一下想法好了。這種型別的題本質是在挖掘狀態中間的特殊性,就像莫名其妙看出這個是凸的一樣,這個題可以發現一些狀態在區間上連續,一些轉移在值域上單調,然後通過勢能均攤分析,可以得到非常玄妙的複雜度。這種題現在我反正是做不來的,就慢慢見識見識吧。

code:

#include const int n=5e5+10;

const int inf=0x7fffffff,mod=1e9+7;

struct node

node(int val,int cnt)

}s0[n],s1[n];

int t,n,a[n],tot0,tot1;

int main()

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

s0[tot0=0]=node(inf,1);//增

s1[tot1=0]=node(-inf,1);

for(int i=2;i<=n;i++)

if(a[i]>a[i-1])//得把那個s1推了

else

{int t0=a[i]>s1[0].val?s1[0].cnt:0;

int t1=a[i]2019.1.1

Block Voting 解題報告

這道題做的有點狼狽,效率不高,差一點就tle的ac了。看status裡的,ac的時間大多數都是0ms的。肯定有乙個更有效率的演算法的。下面說下我的狼狽演算法。出處 http acm.jlu.edu.cn joj showproblem.php?pid 1223 問題描述 求每個party的權值。第i...

Safebreaker 解題報告

又是吉林大學一道acm題目,題目很簡單,直接暴力解決。出處 http acm.jlu.edu.cn joj showproblem.php?pid 1718 問題描述 對乙個給定數0000 9999 根據一系列猜測,判斷這個數是否存在,存在的話,是否唯一 例如 3321,給定數 作出猜測,1223 ...

路由 解題報告

路由 問題描述 有乙個tcp ip網路 每台計算機都有乙個或多個網路介面。每個介面根據它的ip位址和子網掩碼來識別 即兩個4位元組的數,兩個字 節之間有乙個 號.子網掩碼有乙個二進位制表示法 有k個 1 然 後是 m 個 0 k m 8 4 32 如 212.220.35.77 是乙個 ip 地 址...