日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【正睿2021寒假省选第二轮集训 day 1】令牌生成 (组合数+二分)

發(fā)布時(shí)間:2023/12/3 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【正睿2021寒假省选第二轮集训 day 1】令牌生成 (组合数+二分) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

description

solution

打表yyds
其實(shí)符合條件的個(gè)數(shù)跟nnn(非題目中的意思)有著等差數(shù)列公式的千絲萬縷關(guān)系
所以可以二分出具體值
最后答案的取值范圍一定是長(zhǎng)成[,)[,)[,),左閉右開的形式的
而且兩個(gè)邊界一定是只差了最小的那個(gè)111,那么答案的二進(jìn)制長(zhǎng)相也是固定的

同樣二分出111的具體位置即可
這里與組合數(shù)掛鉤,可以預(yù)處理部分小的組合數(shù)降低查詢時(shí)間復(fù)雜度

私以為還是有思維難度的!

code

#include <iostream> #include <cstdio> #include <cmath> using namespace std; #define MAX 1e18 #define ll long long #define mod 998244353 ll c[3005][3005];ll qkpow1( ll x, ll y ) {ll ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans; }ll qkpow2( ll x, ll y ) {ll ans = 1;while( y ) {if( y & 1 ) ans *= x;x *= x;y >>= 1;}return ans; }ll calc( ll n ) {return n * ( n + 1 ) >> 1; }ll C( ll n, ll m ) {if( n <= 3000 && m <= 3000 ) return c[n][m];if( m > n - m ) m = n - m;if( n >= 1e7 && m >= 3 ) return MAX + 1;__int128 d1 = 1, d2 = 1;for( int i = 1;i <= m;i ++ ) d1 *= i;for( int i = n - m + 1;i <= n;i ++ ) {d2 *= i;if( d2 > d1 * MAX ) return MAX + 1;}return d2 / d1; }void solve( ll n, ll k, ll ans ) {ll t = 0, tmp;while( k > ( tmp = C( n, t ) ) ) k -= tmp, t ++;int last = n;for( ll i = 1;i <= t;i ++ ) {ll l = 1, r = last, pos;while( l <= r ) {ll mid = ( l + r ) >> 1;if( C( mid - 1, t - i + 1 ) < k ) pos = mid, l = mid + 1;else r = mid - 1;}last = pos - 1;k -= C( pos - 1, t - i + 1 );ans = ( ans + qkpow1( 2, pos - 1 ) ) % mod;}printf( "%lld\n", ans ); }void init( int n = 3000 ) {for( int i = 0;i <= n;i ++ )for( int j = 1;j <= i;j ++ )c[i][j] = MAX + 1;for( int i = 0;i <= n;i ++ ) {c[i][0] = 1;for( int j = 1;j <= i;j ++ )c[i][j] = min( c[i][j], c[i - 1][j] + c[i - 1][j - 1] );} }int main() {init();int T; ll n, k;scanf( "%d", &T );while( T -- ) {scanf( "%lld %lld", &n, &k );ll t = sqrt( n << 1 );while( calc( t ) > n ) t --;ll t1 = n - calc( t ), t2 = t - t1;if( ! t1 ) {if( k == 1 ) printf( "%lld\n", ( qkpow1( 2, t ) - 1 + mod ) % mod );else printf( "-1\n" );}else if( t2 < 60 && qkpow2( 2, t2 ) < k )printf( "-1\n" );else solve( t2, k, ( qkpow1( 2, t1 ) - 1 + mod ) % mod * qkpow1( 2, t2 + 1 ) % mod );}return 0; }

總結(jié)

以上是生活随笔為你收集整理的【正睿2021寒假省选第二轮集训 day 1】令牌生成 (组合数+二分)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。