2020.11.23
題目只要求求出 \(c\) 的值,它就提示我們 \(c\) 和 \(a\)、\(b\) 的值沒有太大關係。照著這個思路我們把 \(a\)
\(b\) 合併一下,搞成二元組。對 \(a+b\leq c\),\((a+b,c)\to(2(a+b),c-(a+b))\),對 \(a+b>c\),\((a+b,c)\to((a+b)-c,2c)\)。我們發現 \(ab\) 始終可以並在一起,乾脆直接記為 \(d\)。對 \(d\leq c\),\((d,c)\to(2d,c-d)\),對 \(d>c\),\((d,c)\to(d-c,2c)\)。這兩個式子有很大的共性,可以說成是對稱的。
while(k--)
(然而這波並沒有任何的加成效果)
再觀察,發現 \(2c\) 可以寫成 \(c+c\),又左邊是 \(d-c\),那麼二元組內的和是沒有變的,始終為 \(a+b+c\)。(這大概又提示我們和模運算有關?)
這個暴力不能優化的原因在於其中一條語句執行了一定次數,就會跳過去執行另一條語句。實際上是交換 \(a\) 和 \(c\) 的值(因為式子是對稱的)。大膽嘗試,如果到了臨界點不交換會發生什麼,令 \(s=c+d\) ,那麼 \(c+c=c+(s-d)=(c-d)+s\) 和 \(d-c=d-(s-d)=2d-s\)。我們發現這交不交換的本質其實是一樣的,只不過區別於有沒有加上乙個 \(s\) 即 \(a+b+c\),所以可以一直乘 \(2\),然後對 \(s\) 取模即可。
#include#define ll long long
#define n 100007
inline int read()
while(c>='0'&&c<='9')
return flag? x:-x;}
ll a,c,mod;
int t,k;
ll qpow(ll x,ll y)
return ret;}
int main()
}
2020多校聯考 簡單題
確實是簡單題。邊權和最小顯然是最小生成樹。對於一條非樹邊,加到樹裡面一定會構成乙個環,那麼環上的樹邊的邊權就一定不能超過這條非樹邊。所以對最小生成樹進行重鏈剖分,對於一條非樹邊 u i,v i 對鏈 u i to v i 進行 modify 維護乙個最小值。而對於一條非樹邊要想成為樹邊,就至少需要把...
2020多校聯考 樹
沒有定根就非常的離譜,後來告訴根直接就是 1 先考慮鏈上怎麼做,顯然維護乙個單調棧,求出第乙個比當前數大的位置,然後倍增即可。再放在樹上怎麼做?依舊維護單調棧,但這次不能暴力地彈掉棧頂元素了,因為這樣的複雜度是假的。因為單調棧有單調性,所以直接在單調棧內二分出單調棧彈得不能再彈的位置,然後修改 to...
2020多校聯考 手套
有兩個可重集 a 和 b 每個集合裡有若干元素,每種元素有若干個。可以選擇從 a 集中等概率隨機選 x 個到 c 集 從 b 中等概率隨機選擇 y 個到 d 使得一定會使 c 和 d 有交。最小化 x y 在 x y 相等時最小化 x 因為要使得一定有交,所以考慮選了一定數目後,沒有交的最壞情況。最...