HZOI20190829模拟33题解

Posted juve

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HZOI20190829模拟33题解相关的知识,希望对你有一定的参考价值。

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

A:春思

我们对a分解质因数,则$a=\\prod\\limits_p^p|ap^k$

所以$a^b=\\prod\\limits_p^p|ap^k*b$

所以$ans=\\prod\\limits_p^p|a\\sum\\limits_q=0^k*bp^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\\n",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\\n",-ans-1);
	
	return 0;

C:赤壁情

咕咕咕~~

以上是关于HZOI20190829模拟33题解的主要内容,如果未能解决你的问题,请参考以下文章

HZOI20190908模拟40 队长快跑,影魔,抛硬币 题解

CSP-S 模拟测试57题解

HZOI20190817模拟24

HZOI20190816模拟23 mine/water/gcd

牛客白月赛33题解 待补

COGS 2188. [HZOI 2015] Math 题解