2016"百度之星" - 资格赛(Astar Round1)

题目链接:http://bestcoder.hdu.edu.cn/contests/contest_show.php?cid=690


Problem A

思路:先预处理开始位置到每一个位置的结果。假设要求区间为[a,b],开始位置到位置i的结果为f(i),那么区间[a,b]所求结果为f(b)/f(a-1),但是不一定能整除,所以需要处理一下。因为模为p=9973,是一个素数。根据费马小定理,假设p是一个素数,且(a,p)=1,那么a^(p-1)≡1 (mod p)。即:假如a是整数,p是素数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。所以,假设x≡f(b)/f(a-1) (mod p)(这里的p即为题中的模),又有(f(a-1))^(p-1) ≡ 1 (mod p),根据同余性质,有x≡f(b)*(f(a-1))^(p-2) (mod p),此即为答案。

附上AC代码:

#include <iostream>
#include <algorithm>
using namespace std;
const int mod = 9973;
const int maxn = 100005;
int h[maxn];
int n;
string str;

int quick_pow(int a, int b){
	int ans = 1;
	while (b){
		if (b & 1)
			ans = ((ans%mod)*(a%mod))%mod;
		a = ((a%mod)*(a%mod))%mod;
		b >>= 1;
	}
	return ans;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	while (cin >> n){
		cin >> str;
		h[0] = 1;
		for (int i=1; i<=str.size(); ++i)
			h[i] = (h[i-1]*(str[i-1]-28))%mod;
		int a, b;
		while (n--){
			cin >> a >> b;
			if (a > b)
				swap(a, b);
			int t = quick_pow(h[a-1], mod-2);
			int ans = (h[b]*t)%mod;
			cout << ans << endl;
		}
	}
	return 0;
}

Problem B

思路:明显的斐波拉契数列,因为n很大,所以用Java实现。

附上AC代码:

import java.util.Scanner;
import java.math.BigInteger;
import java.util.Arrays;
import java.math.BigDecimal;
public class Main{
	final static int MAXN = 205;
	public static void main(String args[]){
		Scanner in = new Scanner(System.in);
		BigInteger fac[] = new BigInteger[MAXN];
		fac[0] = fac[1] = BigInteger.ONE;
		for (int i=2; i<MAXN; ++i)
			fac[i] = fac[i-1].add(fac[i-2]);
		while (in.hasNext()){
			int n = in.nextInt();
			System.out.println(fac[n]);
		}
		in.close();
	}
}

Problem D

思路:因为数据不是太大,所以直接map搞定。直接上代码吧!

附上AC代码:

#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
map<string, int> cnt;
int n;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	string str;
	while (n--){
		cin >> str;
		sort(str.begin(), str.end());
		cout << cnt[str] << endl;
		++cnt[str];
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值