zoukankan      html  css  js  c++  java
  • Solution -「多校联训」染色

    (mathcal{Description})

      Link.

      给定 (n)(q) 次询问,每次询问给出 (x,k),求第 (x) 位为 0 且任意两个 1 的下标之差不小于 (k) 的长度为 (n) 的 01 序列数量。

      (n,qle10^5)

    (mathcal{Solution})

      “不小与 (k)”可能在复杂度中体现为“(div k)”,考虑根号分治。

      对于 (klesqrt n),预处理 (f(k,i)) 表示不考虑 (x) 的限制,长度为 (i) 的序列数量。通过全局答案减去 (x) 位为 1 的答案可以 (mathcal O(1)) 回答询问;

      而对于 (k>sqrt n)1 的数量 (lesqrt n),枚举 1 的数量,把 0{k-1}1 看做一整块,可以隔板法求方案,在用总方案减去左右方案之积即可 (mathcal O(sqrt n)) 回答询问。

      最终,得到复杂度最坏为 (mathcal O((n+q)sqrt n)) 的算法。

    (mathcal{Code})

    /* Clearink */
    
    #include <cmath>
    #include <cstdio>
    
    #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
    #define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
    
    const int MAXSN = 316, MAXN = 1e5, MOD = 998244353;
    int n, q, thres, f[MAXSN + 5][MAXN + 5], fac[MAXN * 2 + 5], ifac[MAXN * 2 + 5];
    
    inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
    inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }
    inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
    inline int mpow( int a, int b ) {
    	int ret = 1; 
    	for ( ; b; a = mul( a, a ), b >>= 1 ) ret = mul( ret, b & 1 ? a : 1 );
    	return ret;
    }
    
    inline void init() {
    	fac[0] = 1;
    	rep ( i, 1, 2 * n ) fac[i] = mul( i, fac[i - 1] );
    	ifac[2 * n] = mpow( fac[2 * n], MOD - 2 );
    	per ( i, 2 * n - 1, 0 ) ifac[i] = mul( i + 1, ifac[i + 1] );
    
    	rep ( i, 1, thres ) {
    		int* fi = f[i]; *fi = 1;
    		rep ( j, 1, n ) fi[j] = add( fi[j - 1], j >= i ? fi[j - i] : 1 );
    	}
    }
    
    inline int comb( const int n, const int m ) {
    	return n < 0 || n < m ? 0 : mul( fac[n], mul( ifac[m], ifac[n - m] ) );
    }
    
    int main() {
    	freopen( "color.in", "r", stdin );
    	freopen( "color.out", "w", stdout );
    
    	scanf( "%d %d", &n, &q ), thres = sqrt( n );
    
    	init();
    
    	for ( int x, k; q--; ) {
    		scanf( "%d %d", &x, &k );
    		if ( k <= thres ) {
    			printf( "%d
    ", sub( f[k][n], mul( x >= k ? f[k][x - k] : 1,
    				n + 1 >= x + k ? f[k][n - x - k + 1] : 1 ) ) );
    		} else {
    			int all = 0, lcnt = 0, rcnt = 0;
    			rep ( i, 0, ( n + k - 1 ) / k ) {
    				all = add( all, comb( n + k - 1 - i * k + i, i ) );
    				lcnt = add( lcnt, comb( x - 1 - i * k + i, i ) );
    				rcnt = add( rcnt, comb( n - x - i * k + i, i ) );
    			}
    			printf( "%d
    ", sub( all, mul( lcnt, rcnt ) ) );
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    ios 分享腾讯微博
    ios 分享微信
    elinput 价格校验 大于0保留2位小数,不包含01,01.1这种
    从范闲到许乐,从宁缺再到陈长生
    二进制流 ajax 实现图片上传
    php 操作redis 部分命令
    matlab 与vs2008联合编程的设置备忘
    新型机器人闯入职场:到底是工作缔造者还是工作终结者?
    c++ vs2008 多线程编程的样例
    虚拟试衣创业公司Fitiquette被印度电商Myntra收购
  • 原文地址:https://www.cnblogs.com/rainybunny/p/14893031.html
Copyright © 2011-2022 走看看