zoukankan      html  css  js  c++  java
  • Codeforces 1188E Problem from Red Panda (计数)

    题目链接

    https://codeforces.com/contest/1188/problem/E

    题解

    我们可以发现,题目要求数的目标状态的个数,实际上就是在数操作序列(指每个气球操作的次数构成的序列,第 (i) 个颜色操作 (b_i) 次)的个数。可以发现如果给定了操作序列,每次一定是操作那个剩下的 (a_i) 最小的。那么对于一个合法序列 (b),将其每个元素减去 (1) 后一定合法,且得到的序列不变。那么我们可以通过强制至少一个 (b_i=0) 来保证不算重。
    然后我就卡住了。。。。。手动再见
    考虑每种颜色对序列合法的限制,就是对每个 (i),前 (a_i+mk+1 (m=0,1,2,...)) 次操作至少要有一次操作 (i). 那么从小到大枚举操作总数 (s) ((0le sle max a_i)),我们可以得到某些必须进行的操作,剩余的操作分配给 (k) 种颜色,使用插板法计算。为了保证存在 (b_i=0),再减去强制给每个未出现限制的 (b_i)(+1) 的方案数。
    时间复杂度 (O(k+max a_i)).

    代码

    #include<bits/stdc++.h>
    #define llong long long
    #define mkpr make_pair
    #define iter iterator
    #define riter reversed_iterator
    #define y1 Lorem_ipsum_dolor
    using namespace std;
    
    inline int read()
    {
    	int x = 0,f = 1; char ch = getchar();
    	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
    	return x*f;
    }
    
    const int mxN = 1e6;
    const int P = 998244353;
    llong fact[mxN*2+3],facti[mxN*2+3];
    int a[mxN+3];
    int cnt[mxN+3],cnt2[mxN+3];
    int n,mx;
    
    llong quickpow(llong x,llong y)
    {
    	llong cur = x,ret = 1ll;
    	for(int i=0; y; i++)
    	{
    		if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
    		cur = cur*cur%P;
    	}
    	return ret;
    }
    llong comb(llong x,llong y) {return x<0||y<0||x<y?0ll:fact[x]*facti[y]%P*facti[x-y]%P;}
    
    void updsum(llong &x,const llong y) {x = x+y>=P?x+y-P:x+y;}
    
    void initfact(int n)
    {
    	fact[0] = 1ll; for(int i=1; i<=n; i++) fact[i] = fact[i-1]*i%P;
    	facti[n] = quickpow(fact[n],P-2); for(int i=n-1; i>=0; i--) facti[i] = facti[i+1]*(i+1ll)%P;
    }
    
    int main()
    {
    	initfact(mxN*2);
    	n = read();
    	for(int i=1; i<=n; i++) a[i] = read(),mx = max(mx,a[i]);
    	for(int i=1; i<=n; i++)
    	{
    		for(int j=a[i]+1; j<=mx; j+=n) {cnt[j]++;} cnt2[a[i]+1]++;
    	}
    	llong ans = 0ll;
    	for(int i=0,j=0,k=n; i<=mx; i++,j++)
    	{
    		j-=cnt[i],k-=cnt2[i];
    //		printf("i=%d j=%d k=%d
    ",i,j,k);
    		if(j<0) break;
    		llong tmp = comb(j+n-1,n-1);
    		updsum(ans,tmp);
    		if(j-k>=0)
    		{
    			llong tmp = comb(j-k+n-1,n-1);
    			updsum(ans,P-tmp);
    		}
    	}
    	printf("%I64d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    learnVUEnote
    DOUAudioStreamer 中kqueue的应用
    OpenGL ES 2.0 渲染管线 学习笔记
    顶点着色器 学习笔记
    XCode 8.3 Automatically manage signing 问题
    【暴力】【几何】Codeforces Round #431 (Div. 2) B. Tell Your World
    标题
    【枚举】【gcd】Codeforces Round #432 (Div. 2) D. Arpa and a list of numbers
    【预处理】Codeforces Round #433 853B. Jury Meeting
    【构造】【规律】Codeforces Round #431 (Div. 2) C. From Y to Y
  • 原文地址:https://www.cnblogs.com/suncongbo/p/12591476.html
Copyright © 2011-2022 走看看