2019牛客多校第二場

2022-08-04 07:54:09 字數 4211 閱讀 2728

upsloved

有乙個長為\(n\)的環,一開始位於\(0\),每次隨機向前或者向後走,求最後乙個走到\(m\)的概率

ps:這題實際上求的是所有詢問的字首積

實際上概率相等(俺也不知道為啥)如果\(m!=0\),則概率是\(\frac 1 \),特判\(n=1,m=0\)就行了

**不放了

solved at 03:54(+2)

有乙個無限長的序列,一開始位於\(0\),每次概率均等地往前走\(1\)到\(k\)步,求經過\(n\)的概率

\(1<=n<=1e18, 1<=k<=1000\)

如果\(n=-1\)表示求\(n\)趨近於正無窮時的概率

顯然\(dp[i] = \sum\limits_^dp[j]\)

這是個線性遞推式,我們賽中bm搞過去了...

\(n=-1\)時小資料打表發現是\(\frac 2 \)

矩陣快速冪是\(k^3\log(n)\)的,據說可以利用轉移矩陣和特徵方程的聯絡優化成\(k^2\log(n)\)的,並不是很懂,可以搜叉姐**看一看

**也沒啥好放的

upsloved

\(n\)個點的帶點權的圖,求權值第\(k\)小的完全子圖的權值\(1<=n<=100, 1<=k<=1e6)\)

看著咖啡雞的**恍然大悟,咖啡雞nb

用優先佇列儲存當前完全子圖,然後嘗試往這個圖里塞乙個點,為避免重複只塞下標比當前完全子圖最大點下標還要大的點,複雜度大概是\(k\log(k)+kn^2/64\)

#include using namespace std;

using bs = bitset<105>;

using ll = long long;

struct node

};int s[105][105], n, a[105], k;

bs f[105];

int main()

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

} priority_queuepq;

bs p;

p.reset();

pq.push();

while(!pq.empty())

int pos = 0;

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

if(u.mask[i])

pos = i + 1;

for(int i = pos; i < n; ++i) if((f[i] & u.mask) == u.mask) );

u.mask[i] = 0;

} }puts("-1");

return 0;

}

upsolved

你有乙個\(n*m\)的\(01\)矩陣,\(1\)代表牆,你每次可以往下,左,右走(不能往上,也不能走回頭路)

有兩種操作

1.修改\(i, j\)位置的矩陣狀態

2.詢問從\(1, a\)走到\(n, b\)的方案數

設\(dp[l][r][i][j]\)代表從\(l, i\)走到\(r,j\)的方案數

顯然\(dp[l][r][i][j] = \sum\limits_^mdp[l][x][i][k]*dp[x+1][r][k][j]\),\(x\)是\(l\)到\(r-1\)之間的任意乙個值

因為不能走回頭路,相當於列舉怎麼從\(x\)走到\(x+1\)的

然後這個東西顯然可以用線段樹,支援\(o(m^3\log(n))\)修改, \(o(1)\)查詢

總複雜度是\(o(q*m^3\log(n)+m^3n)\)

#include using namespace std;

const int mod = 1e9 + 7, n = 5e4 + 10;

int n, m, q, b[n][10], x, y, z;

char s[14];

struct matrix

}tree[n << 2];

void pushup(int rt)

void calc(int b, matrix &c)

}void build(int rt, int l, int r)

int mid = l + r >> 1;

build(rt << 1, l, mid);

build(rt << 1 | 1, mid + 1, r);

pushup(rt);

}void update(int rt, int l, int r, int pos)

int mid = l + r >> 1;

if(pos <= mid)

update(rt << 1, l, mid, pos);

else

update(rt << 1 | 1, mid + 1, r, pos);

pushup(rt);

}int main()

build(1, 1, n);

while(q--)

else

} return 0;

}

solved at 02:38(+3)

有\(2n\)個人,把他們分為大小各為\(n\)的兩個集合,不在同乙個集合裡的人會獲得貢獻\(v_\),求最大貢獻

\((1<=n<=14)\)

比賽的時候並沒有發現\(c_^\)只有4e7, 可以直接\(o(n*c_^)\)dfs過去

比賽的時候我寫了個折半搜尋,打了四個表,實際上複雜度也是\(o(n*c_^)\)的...

折半的兩個東西拼起來的時候要一些騷操作,不然很容易變成\(2*n*c_^\)的或者是\(n*2^\)的

#include using namespace std;

const int n = 10 + (1 << 14);

long long dp[n], dp2[n];

long long p[14][n], p2[14][n], ans;

int a[28][28], n, t[n], f[n];

int c[n], tot;

vectorv[15];

int main()

} tot = (1 << n) - 1;

c[0] = 0;

v[0].push_back(0);

for(int i = 1; i <= tot; ++i)

f[0] = 1;

t[f[0]] = 0;

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

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

}p[i][mask] = val;

} }for(int i = 0; i < n; ++i)

}p2[i][mask] = val;

} }for(int mask = 0; mask <= tot; ++mask)

} }for(int mask = 0; mask <= tot; ++mask)

} }for(int mask = 0; mask <= tot; ++mask)

} printf("%lld\n", ans);

return 0;

}

solved at 01:00(+2)

有乙個\(n*m\)的\(01\)矩陣,求面積第二大的全\(1\)子矩陣面積\(1<=n,m<=1000\)

最大的是用懸線法\(o(nm)\)處理出來,第二大的也差不多,把每個位置對應的最大的要麼行減一,要麼列減一,第二大的肯定在這些裡面

注意可能很多位置的最大全\(1\)子矩陣是同乙個矩陣,標記掉就好了

#include using namespace std;

const int n = 1010;

int a[n][n], d[n][n], s[n][n], s2[n][n], mx, mx2, n, m, vis[n][n];

int main()

for(int j = 1; j <= m; ++j)

} for(int i = 1; i <= n; ++i)

} for(int i = 1; i <= n; ++i)

} for(int i = 1; i <= n; ++i)

} printf("%d\n", mx2);

return 0;

}

upsolved

開場就有人過,看了半天不怎麼會,沒想到是個暴力

參考部落格

2019牛客多校第二場

蒙特卡洛 猜答案 注意答案要累乘 最大的可以用rmq rmqrm q做然後挖掉四個角分別再做一次即可 掛一下大佬的鏈結 最重要的是學會了字首和查詢相差為1 11的時候的奇技淫巧 include include define fo i,a,b for i a i b i define fd i,a,b...

2019牛客多校第二場

乙個0到n 1的環,初始在0,每次隨機前進或後退一格,當所有點都訪問過就結束,問結束時站在k的概率是多少。注意輸出的是字首積 一開始站在0,最後顯然不可能在0,剩下n 1格,隨機數打表發現概率相同,都為 frac include using namespace std typedef long lo...

牛客多校第二場 J farm

輸入描述 the first line of input contains 3 integers n,m,t n m 1000000,t 1000000 for the next n lines,each line contains m integers in range 1,n m denotin...