2017中国大学生程序设计竞赛-杭州站-重现赛(感谢浙江理工)

A Super-palindrome 找规律+回文子串 字符串
B Master of Phi 积性函数+欧拉函数 数学题
C Hakase and Nano 博弈论
D Master of Random 找规律+逆元 数学题
J Master of GCD 数论gcd

A Super-palindrome

签到题,因为要每一个奇数长度的子串都要是回文串,所以因该是以三为单位,行程回文串,就是关于奇数位,偶数位和全部讨论,选择变化小的输出,具体的看代码

# include <bits/stdc++.h>
using namespace std;

int j[30];
int o[30];
int q[30];
int main()
{
	int T;
	scanf("%d",&T);
	
	while(T--){
		for(int i=0;i<30;i++){
			j[i]=0;
			o[i]=0;
			q[i]=0;
		}
		string s;
		cin>>s;
		
		int maxj=0,maxo=0,maxq=0;
		for(int i=0;i<s.length();i++){
			if(i%2==0){
				j[s[i]-'a']++;
				//cout<<j[s[i]-'a']<<endl;
				if(j[s[i]-'a']>maxj) maxj=j[s[i]-'a'];
			}else{
				o[s[i]-'a']++;
				if(o[s[i]-'a']>maxo) maxo=o[s[i]-'a'];
			}
			q[s[i]-'a']++;
		}
		
		int a=s.length()-maxj-maxo;
		int b=s.length()-maxq;
		//cout<<"####"<<maxj<<" "<<maxo<<endl;
		//cout<<"@@@@"<<a<<" "<<b<<endl;
		printf("%d\n",min(a,b));
		
	}
	
	return 0;
}

B Master of Phi

证明

# include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL mod=998244353;
LL quick_pow(LL a,LL b,LL n)
{
	LL ret=1;
	while(b)
	{
		if(b&1) ret=ret*a%n;
		a=a*a%n;
		b=b/2;
	}
	return ret%n;
}
int main()
{
	int T;
	scanf("%d",&T);
	
	while(T--){
		int m;
		scanf("%d",&m);
		LL ans=1;
		for(int i=1;i<=m;i++){
			LL p,q;
			LL cnt=1;
			scanf("%lld %lld",&p,&q);
			cnt=(((p%mod+((p%mod)*(q%mod))%mod)%mod-q+mod)%mod)%mod;
			//cout<<cnt<<endl;
			//cout<<"@@@@   "<<ans%mod<<endl;
			ans=(((ans*quick_pow(p,q-1,mod))%mod)*cnt)%mod;
			//cout<<"@@@"<<" "<<(quick_pow(p,q-1,mod)%mod)<<" "<<cnt%mod<<endl;
		}
		printf("%d\n",ans);
	}
	
	return 0;
}

C Hakase and Nano

博弈论

# include <bits/stdc++.h>
using namespace std;

const int MAXN=1e6+100;
int a[MAXN];
int main()
{
	int T;
	scanf("%d",&T);
	
	while(T--){
		int n,d;
		int cnt=0;
		int flag;
		scanf("%d %d",&n,&d);
		//d=1 Hakase 
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			if(a[i]==1) cnt+=a[i];
		}
		if(d==1){
			if(cnt%3==0&&cnt==n) flag=0;
			else flag=1;
		}else{
			if(cnt%3==1&&cnt==n) flag=0;
			else if(n%3==1&&cnt==(n-1)) flag=0;
			else if(n%3==0&&cnt==(n-1)) flag=0;
			else flag=1;
		}
		if(flag) printf("Yes\n");
		else printf("No\n");
	}
	
	return 0;
}

D Master of Random

以下是找出的规律,就是因为是要找子树的和,然后我们先不管每一个点到底是什么值,对于一个在n层的节点,他对于整个子树的贡献度是n(然后如果要算子树和的话,那么就是n*ai就好了),关于编号为i的节点,他在哪一层的规律如下,将层数和次数乘起来就是改节点的贡献度。关于整个贡献度的计算规律如下就是,每一层的差就是当前是树形数分别除以当前的层数就是和下一层的差,然后首项是树形数,那么就可以算贡献度了。然后再求逆元就可以了。
证明

#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;

#define IOC std::ios::sync_with_stdio(false)
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uit;
typedef long double LD;
typedef pair<int,int> pii;
const int INF = 0x3f3f3f3f;
const long double eps = 1e-10;
const double pi = acos(-1.0);
inline LL read()
{
	LL X=0,w=0; char ch=0;
	while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void write(LL x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
//-------head------------
const int maxn = 1e5 + 10;
const LL mod = 998244353;

LL inv[maxn],fact[maxn],pre[maxn];

inline LL quickpow(LL x,LL y){
	LL ans = 1;
	while(y){
		if(y & 1) ans = ans * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return ans;
}
inline void expow(LL b,LL p,LL &a,LL &k ) {
	if(p == 0) {
	a = 1; k = 0;
	return;
	}
	expow( p, b % p, k, a );
	k -= b / p * a;
	return;
}
LL exinv(LL b,LL p ) {
	LL a,k;
	expow(b,p,a,k);
	if(a < 0) a += p;
	return a;
}
LL dict[maxn];
int main(){
	LL n = 1e5 + 3;
	fact[0] = 1;
	for(LL i = 1; i <= n; ++i){
		fact[i] = fact[i-1] * i % mod;
	}
	inv[n] = exinv(fact[n],mod);
	for(int i = n - 1; i >= 0; --i){
		inv[i] = inv[i + 1] * (i + 1) % mod;
	}
	pre[0] = pre[1] = 1;
	for(int i = 2; i <= n; i++ )
		pre[i] = (mod - mod / i) * pre[mod % i] % mod;
	
	int t = read();
	while(t--){
		int n = read();
		LL ans = 0,tmp = 0;
		for(int i = 1; i <= n; ++i) dict[i] = read();
		for(int i = 1; i <= n; ++i){
			tmp = (tmp + fact[n - 1] * pre[i - 1] % mod) % mod;
			ans = (ans + tmp * dict[i] % mod) % mod;
		}
		ans = ans * inv[n] % mod;
		printf("%lld\n",ans);
	}
	return 0;
}

J Master of GCD

队友写的,所以没有解释

//J
#include <bits/stdc++.h>
using namespace std;
using namespace __gnu_cxx;


#define IOC std::ios::sync_with_stdio(false)
typedef long long LL;
typedef unsigned long long uLL;
typedef unsigned int uit;
typedef long double LD;
typedef pair<int,int> pii;
const int INF = 0x3f3f3f3f;
const long double eps = 1e-10;
const double pi = acos(-1.0);
inline LL read()
{
	LL X=0,w=0; char ch=0;
	while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
	while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
	return w?-X:X;
}
inline void write(LL x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
//-------head------------
const int maxn = 1e5 + 10;
LL pre1[maxn],pre2[maxn];

const LL mod = 998244353;
LL quickpow(LL x,LL y){
	LL ans = 1;
	while(y){
		if(y & 1) ans = ans * x % mod;
		x = x * x % mod;
		y >>= 1;
	}
	return ans;
}
void init(){
	memset(pre1,0,sizeof pre1);
	memset(pre2,0,sizeof pre2);
}
int main(){
	int t = read();
	while(t--){
		int n = read(),m = read();
		init();
		for(int i = 0; i < m; ++i){
			int l = read(),r = read(),x = read();
			if(x == 2){
				pre1[l]++,pre1[r + 1]--;
			}
			else{
				pre2[l]++,pre2[r + 1]--;
			}
		}
		LL mmin1 = 1e9,mmin2 = 1e9;
		for(int i = 1; i <= n; ++i){
			pre1[i] += pre1[i - 1];
			pre2[i] += pre2[i - 1];
			//cout << pre1[i] << " " << pre2[i] << endl;
			mmin1 = min(mmin1,pre1[i]);
			mmin2 = min(mmin2,pre2[i]);
		}
		//cout << mmin1 << "?" << mmin2 << endl;
		LL ans = quickpow(2,mmin1);
		ans = ans * quickpow(3,mmin2) % mod;
		cout << ans << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值