• HZOI20190829模拟33题解


    题面:https://www.cnblogs.com/Juve/articles/11436771.html

    A:春思

    我们对a分解质因数,则$a=prodlimits_p^{p|a}p^k$

    所以$a^b=prodlimits_p^{p|a}p^{k*b}$

    所以$ans=prodlimits_p^{p|a}sumlimits_{q=0}^{k*b}p^q$

    然后等比数列求和

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define int long long
    using namespace std;
    const int MAXN=1e2+5;
    const int mod=9901;
    int a,b,num[MAXN],sum=0,ans=1,d[MAXN];
    int q_pow(int a,int b,int p){
    	int res=1;
    	while(b){
    		if(b&1) (res*=a)%=p;
    		(a*=a)%=p;
    		b>>=1;
    	}
    	return res;
    }
    signed main(){
    	scanf("%lld%lld",&a,&b);
    	for(int i=2;i*i<=a;i++){
    		if(a%i==0){
    			d[++sum]=i;
    			while(a%i==0){
    				num[sum]++;
    				a/=i;
    			}
    			(num[sum]*=b)%=(mod-1);
    		}
    	}
    	if(a>1) d[++sum]=a,num[sum]=b%(mod-1);
    	for(int i=1;i<=sum;i++)
    		(ans*=(q_pow(d[i]%mod,(num[i]+1)%(mod-1),mod)-1+mod)%mod*q_pow((d[i]-1)%mod,mod-2,mod)%mod)%=mod;
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    B:密州盛宴

    如果我们统计后缀和,规定1为+1,0为-1,则如果有后缀和小于-1就不合法

    如果中间出现了小于-1的情况,就把一个0放到第一的位置,然后把当前位置前的所有数向后移一位

    因为我们要找的是操作的最大值,所以把所有数向后移一定是优的

    然后统计这样的情况

    但其实我们发现,对于上面的方法,扫一遍整个字符串,找出后缀最小值,然后答案就是最小值的相反数减一

    然后我们优化这种方法

    我们发现有循环的字符串

    那么我们在每一个循环的字符串上统计答案

    我们知道如果这一段字符串的和大于0,那么我们在第一段的时候更新答案

    如果小于0,那么在最后一段更新答案

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define int long long
    using namespace std;
    const int MAXN=1e6+5;
    int n,m,ans,res,cnt=0;
    char ch[MAXN];
    struct node{
    	int t,sum,len,minn,cnt;
    }in[MAXN];
    signed main(){
    	while(~scanf("%lld%lld",&n,&m)){
    		if(n+m==0) break;
    		ans=0x7ffffffffffffff;res=cnt=0;
    		for(int i=1;i<=m;i++){
    			scanf("%s%lld",ch+1,&in[i].t);
    			in[i].len=strlen(ch+1);
    			in[i].minn=0x7ffffffffffffff;
    			in[i].sum=in[i].cnt=0;
    			for(int j=in[i].len;j>=1;j--){
    				if(ch[j]=='1') in[i].cnt++;
    				in[i].sum+=(ch[j]=='1'?1:-1);
    				in[i].minn=min(in[i].minn,in[i].sum);
    			}
    			cnt+=in[i].cnt*in[i].t;
    		}
    		if(cnt<n){
    			puts("-1");
    			continue;
    		}
    		in[m+1].sum=in[m+1].t=0;
    		for(int i=m;i>=1;i--){
    			res+=in[i+1].sum*in[i+1].t;
    			if(in[i].sum>=0){
    				ans=min(ans,res+in[i].minn);
    			}else{
    				ans=min(ans,res+in[i].sum*(in[i].t-1)+in[i].minn);
    			}
    		}
    		if(ans>=0) puts("0");
    		else printf("%lld
    ",-ans-1);
    	}
    	return 0;
    }
    

    C:赤壁情

    咕咕咕~~

    **dp

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    int n,m,k,now=1,pre=0,bnd[105],base;
    double ans=0;
    void print(double a,int k){
    	if(k==0) printf("%0.0lf
    ",a);
    	else if(k==1) printf("%0.1lf
    ",a);
    	else if(k==2) printf("%0.2lf
    ",a);
    	else if(k==3) printf("%0.3lf
    ",a);
    	else if(k==4) printf("%0.4lf
    ",a);
    	else if(k==5) printf("%0.5lf
    ",a);
    	else if(k==6) printf("%0.6lf
    ",a);
    	else if(k==7) printf("%0.7lf
    ",a);
    	else if(k==8) printf("%0.8lf
    ",a);
    	else if(k==9) printf("%0.9lf
    ",a);
    }
    double f[2][105][3][15015];
    void work1(){
    	base=7500;
    	f[now][1][0][base-2]=f[now][1][2][base]=1;
        f[now][1][1][base-1]=2;
        bnd[1]=1;
        for(int i=2;i<=n;i++){
            now^=1;pre^=1;
            bnd[i]=min(i,n-i+1);
            int size=min(7500,i*(i+1));
            for(int j=1;j<=bnd[i];j++){
                for(int l=-size+base;l<=size+base;l++)
                    for(int k=0;k<=2;k++)
                        f[now][j][k][l]=0;
    		}
            for(int j=1;j<=bnd[i-1];j++){
                for(int l=-size+base;l<=size+base;l++){
                    f[now][j+1][0][l-i*2]+=f[pre][j][0][l]*(j+1);
                    f[now][j][0][l]+=f[pre][j][0][l]*j*2;
                    f[now][j-1][0][l+i*2]+=f[pre][j][0][l]*(j-1);
                    f[now][j+1][1][l-i]+=f[pre][j][0][l]*2;
                    f[now][j][1][l+i]+=f[pre][j][0][l]*2;
                    f[now][j+1][1][l-2*i]+=f[pre][j][1][l]*j;
                    f[now][j][1][l]+=f[pre][j][1][l]*(j*2-1);
                    f[now][j-1][1][l+2*i]+=f[pre][j][1][l]*(j-1);
                    f[now][j+1][2][l-i]+=f[pre][j][1][l];
                    f[now][j][2][l+i]+=f[pre][j][1][l];
                    f[now][j+1][2][l-2*i]+=f[pre][j][2][l]*(j-1);
                    f[now][j][2][l]+=f[pre][j][2][l]*(j*2-2);
                    f[now][j-1][2][l+2*i]+=f[pre][j][2][l]*(j-1);
                }
            }
        }
    	for(int i=m;i<=base;i++) ans+=f[now][1][2][i+base];
        for(int i=2;i<=n;i++) ans/=(double)i;
    	print(ans,k);
    	return ;
    }
    int floor(__float128 x){
    	for(int i=9;i>=0;--i){
    		if(x>=i)
    			return i;
    	}
    }
    void print__float128(__float128 x,int ws){
    	int sta[55];sta[0]=0;
    	for(int i=1;i<=ws;++i){
    		x*=10;
    		sta[i]=floor(x);
    		x-=floor(x);
    	}
    	x*=10;
    	if(floor(x)>=5) sta[ws]++;
    	for(int i=ws;i;--i){
    		if(sta[i]==10) sta[i]=0,sta[i-1]++;
    	}
    	printf("%d.",sta[0]);
    	for(int i=1;i<=ws;++i) printf("%d",sta[i]);
    	puts("");
    }
    __float128 dp[2][105][3][15015];
    void work2(){
    	base=2000;
    	dp[now][1][0][base-2]=dp[now][1][2][base]=1;
        dp[now][1][1][base-1]=2;
        bnd[1]=1;
        for(int i=2;i<=n;i++){
            now^=1;pre^=1;
            bnd[i]=min(i,n-i+1);
            int size=min(2000,i*(i+1));
            for(int j=1;j<=bnd[i];j++){
                for(int l=-size+base;l<=size+base;l++)
                    for(int k=0;k<=2;k++)
                        dp[now][j][k][l]=0;
    		}
            for(int j=1;j<=bnd[i-1];j++){
                for(int l=-size+base;l<=size+base;l++){
                    dp[now][j+1][0][l-i*2]+=dp[pre][j][0][l]*(j+1);
                    dp[now][j][0][l]+=dp[pre][j][0][l]*j*2;
                    dp[now][j-1][0][l+i*2]+=dp[pre][j][0][l]*(j-1);
                    dp[now][j+1][1][l-i]+=dp[pre][j][0][l]*2;
                    dp[now][j][1][l+i]+=dp[pre][j][0][l]*2;
                    dp[now][j+1][1][l-2*i]+=dp[pre][j][1][l]*j;
                    dp[now][j][1][l]+=dp[pre][j][1][l]*(j*2-1);
                    dp[now][j-1][1][l+2*i]+=dp[pre][j][1][l]*(j-1);
                    dp[now][j+1][2][l-i]+=dp[pre][j][1][l];
                    dp[now][j][2][l+i]+=dp[pre][j][1][l];
                    dp[now][j+1][2][l-2*i]+=dp[pre][j][2][l]*(j-1);
                    dp[now][j][2][l]+=dp[pre][j][2][l]*(j*2-2);
                    dp[now][j-1][2][l+2*i]+=dp[pre][j][2][l]*(j-1);
                }
            }
        }
    	__float128 ans=0;
    	for(int i=m;i<=base;i++) ans+=dp[now][1][2][i+base];
        for(int i=2;i<=n;i++) ans/=(__float128)i;
    	print__float128(ans,k);
    	return ;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&k);
    	if(k<=8) work1();
    	else work2();
    	return 0;
    }
    
  • 相关阅读:
    N25_复杂链表的复制
    N24_二叉树中和为某一路径
    N23_判断是否为二叉搜索树的后序遍历序列
    N22_从上到下打印二叉树
    win7桌面小工具已停止工作解决办法
    C3P0数据库连接池使用
    js中的页面跳转
    怎么用js代码禁止浏览器的前进与后退?
    怎么在 Dos 下运行 PHP 和 MySQL 命令
    80端口被system 占用解决方法
  • 原文地址:https://www.cnblogs.com/Juve/p/11436790.html
Copyright © 2020-2023  润新知