• Codeforces 729 Div.2


    赛时通过 ( ext{A,B,C,D}),排名 (255)

    A

    略。

    B

    绝了,我被这题卡了 (40) 分钟。。。

    考虑所有能被表示出来的数一定是这样的:(a^m+k_1ba^m+k_2ba^{m-1}+dots +k_mb(k_i,min mathbb{N^+}))。枚举 (m),并判断 (n-a^m) 能否被 (b) 整除即可。

    C

    可以发现 (f(i)) 不会很大,因为当 (f(i)=y) 时,(1dots (y-1)) 都需要整除 (i),即 (operatorname{lcm}(1,2,dots,y-1)mid i),而 (operatorname{lcm}(1,2,dots,41)>10^{16})

    于是枚举 (f(i)) 的取值 (y),此时 (i) 需要满足 (operatorname{lcm}(1,2,dots,y-1)mid i land operatorname{lcm}(1,2,dots,y) mid i)。满足条件的 (i)(lfloor frac{n}{operatorname{lcm}(1,2,dots,y-1)} floor-lfloorfrac{n}{operatorname{lcm}(1,2,dots,y)} floor) 个。

    D

    考虑计算每一个 + 操作对答案的贡献。即,钦定一个 + 操作必须选,我们需要计算有多少种方案使得这个 + 操作不会被 pop 掉。

    设这个 + 操作在位置 (i),数字为 (x),那么:

    • 假如一个操作 + y 的位置小于 (i),且 (yle x),那么这个数 (y) 是否被 pop 掉是随意的,但我们需要记录有多少个 (y) 满足 (yle x) 没有被 pop 掉。
    • 假如一个操作 + y 的位置小于 (i),且 (y>x),那么它是否被 pop 掉也是随意的,但需要注意它要在所有 (<x) 的数都被 pop 掉的情况下才能被 pop。而且我们不需要知道有多少个这样的数。
    • 假如一个操作 - 的位置小于 (i),那么它会优先 pop 掉 (<x) 的数。而且当没有 (<x) 的数时,加入这样的操作也是合法的。
    • 假如一个操作 + y 的位置大于 (i),且 (y<x),那么它可以随意地被加入、删除。
    • 假如一个操作 + y 的位置大于 (i),且 (yge x),那么它只能被加入而不能被删除,因为我们需要保证 (x) 没有被删除。
    • 假如一个操作 - 的位置大于 (i),那么仅当 满足 (y<x)(y) 个数大于 (0) 时,这个 - 操作才能被选择。

    注意到上面第一条是 (le) 而第四条是 (<)。这是因为当集合里有多个相同元素时,pop 只会 pop 掉一个。所以我们需要钦定哪一个被 pop 掉。

    大力 dp 即可。

    代码
    #include <cstdio>
    #include <cstring>
    #include <cctype>
    using namespace std;
    #define For(Ti,Ta,Tb) for(int Ti=(Ta);Ti<=(Tb);++Ti)
    #define Dec(Ti,Ta,Tb) for(int Ti=(Ta);Ti>=(Tb);--Ti)
    typedef long long ll;
    const int N=505,Mod=998244353;
    int n;ll a[N],f[N][N],g[N][N];
    int main(){
    	scanf("%d",&n);
    	char tmp[10];
    	For(i,1,n){
    		scanf("%s",tmp);
    		if(tmp[0]=='-') a[i]=-1;
    		else scanf("%lld",&a[i]);
    	}
    	ll ans=0;
    	For(i,1,n){
    		if(a[i]<0) continue;
    		memset(f,0,sizeof f);
    		memset(g,0,sizeof g);
    		f[0][0]=1;
    		For(j,1,i-1){
    			For(k,0,j){
    				if(a[j]<0){
    					if(!k) f[j][k]=(f[j-1][k]*2+f[j-1][k+1])%Mod;
    					else f[j][k]=(f[j-1][k]+f[j-1][k+1])%Mod;
    				}else if(a[j]<=a[i]){
    					if(!k) f[j][k]=f[j-1][k];
    					else f[j][k]=(f[j-1][k-1]+f[j-1][k])%Mod;
    				}else f[j][k]=f[j-1][k]*2%Mod;
    //				printf("f:%d,%d:%lld
    ",j,k,f[j][k]);
    			}
    		}
    		For(k,0,i-1) g[i][k]=f[i-1][k];
    		For(j,i+1,n){
    			For(k,0,j){
    				if(a[j]<0){
    					if(!k) g[j][k]=(g[j-1][k]+g[j-1][k+1])%Mod;
    					else g[j][k]=(g[j-1][k]+g[j-1][k+1])%Mod;
    				}else if(a[j]<a[i]){
    					if(!k) g[j][k]=g[j-1][k];
    					else g[j][k]=(g[j-1][k-1]+g[j-1][k])%Mod;
    				}else g[j][k]=g[j-1][k]*2%Mod;
    //				printf("g:%d,%d:%lld
    ",j,k,g[j][k]);
    			}
    		}
    		ll res=0;
    		For(k,0,n) res=(res+g[n][k])%Mod;
    		ans=(ans+a[i]*res%Mod)%Mod;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    Written by Alan_Zhao
  • 相关阅读:
    python笔记-列表和元组
    T-sql for xml path使用(转)
    除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效。
    VS2015 经常不出现智能提示,代码颜色也没有了
    虚拟机重新决定网卡地址时,老是报错
    模块的命令
    关闭NetworkManager的作用
    centos6上yum安装drbd(内核:2.6.32.696)
    检查硬件变化的命令kudzu
    parted分区和挂载及非交互式操作
  • 原文地址:https://www.cnblogs.com/alan-zhao-2007/p/cf-729-div2.html
Copyright © 2020-2023  润新知