Recent Contest #1(Mar 18-Mar24, 2014)

2014-11-24 11:19:04 · 作者: · 浏览: 0

A 大模拟,我跟lin理解错题意。

#include 
  
   
#include 
   
     using namespace std; int events[100005]; int main() { int t; scanf(%d, &t); for (int i = 1; i <= t; i++) { long long n, a, b, s; cin >> n >> a >> b; s = a * 2 + b; for (int j = 0; j < n; j++) { cin >> events[j]; } for (int j = 1; j < n; j++) { double back, stay; back = a * 2 + b; stay = (events[j] - events[j - 1]) * b; if (back > stay) s = s + stay; else s = s + back; } cout << Case # << i << : << s << endl; } return 0; } 
   
  
E 水概率,没想到这么水。。。!!

#include 
  
   
#include 
   
     using namespace std; int main(){ int t; cin>>t; int kase = 1; while (t--) { int m, k; cin>>m>>k; double ans = 1.0 / ((m+1)*(k)+1); cout << Case # << kase++ << : << fixed << setprecision(8) << ans << endl; } }
   
  

F水题不述。

周五去跟小政政上自习了,啸爷他们自己做的,貌似太难。。

http://acm.sdut.edu.cn:8080/vjudge/contest/view.action cid=103#overview

出题人总结:http://hi.baidu.com/wzc1989/item/56ce9291cdfdc0bf82d29548

B题过的,这。。

#include 
  
   

#define LL long long

using namespace std;

int a[1000005];

int main() {
	int t;
	scanf(%d, &t);
	for (int case1 = 1; case1 <= t; case1++) {
		int n;
		cin>>n;
		LL l = 0, r = 0;
		for (int i = 0; i < n; i++) {
			scanf(%d, &a[i]);
			if (i && a[i] > a[i - 1]) {
				l += (LL)a[i] - a[i - 1];
			}
			if (i && a[i] < a[i - 1]) {
				r += a[i - 1] - a[i];
			}
		}
		cout << Case  < 

呵呵,呵呵,呵呵。

重点是下面这个题

G

做题的时候一直纠结于所谓“部分错排公式”。的确有那么个公式:

n + m 个数中 m 个数必须错排求排列数

\

dp[m] 为所求解

可是这不扯呢么,开都开不开,而且也不能预处理取模运算,存也存不下。。

解题报告:

\ 其中C(n,n - k)表示组合数 H(n - k)表示错排数 由于n,k的规模比较大,于是无法直接暴力 而由于m不一定为square-free-number,多以CRT(Chinese Remainder Theorem)+LUCAS也是无法行得通的。

首先我们先来解决 C(n,k) mod m的问题

做法是先将m分解成若干的素因子的幂次的乘积,之后对于每一个 Pi^Ki 计算 C(n,k) mod Pi^Ki,之后的结果用CRT合并得到 下面介绍如何计算 C(n,k) mod Pi^Ki 做法很简单 \ 我们开一个全局变量,保存C(n,k)中的Pi的个数(可以容易得到)补充:采用整数分解的方式,pollard-rho方法。 \ 现在的问题就是如何处理不含Pi的连续若干个数字的乘积

\

其中Cnt[i]表示(i!)中Pi的个数 \

其中Inv(x) 表示x对m的逆元,C[i]表示i中Pi的个数.补充:对应除一下, 那么

\

Tot 表示C(n,k)中Pi的个数. 显然F[i]表示的是不含有Pi的积 下面考虑F[i] 那么可以预处理得到F[1...m - 1] 可是实际上我们需要的其实是F[n],由于n比较大,没有办法预处理,不过通过观察不难发现F[i]具有周期性,于是可以利用周期性来求解.最后将得到的答案利用CRT合并得到C(n,k) mod m的结果。 之后说说H(n - k)的求法,可以证明 本题 中 H(i) mod m存在周期!于是继续使用周期的思路来处理就可以得到答案。

代码是参考别人思路写出的:

#include 
    
     
#include 
     
       #include 
      
        #include 
       
         #include 
        
          using namespace std; #define F 200 #define M 200010 long long n, K, m; long long mp[F], mr; long long xa[F], xb[F], xc[F]; long long circle[M] = { 1 }; void divide_factor(long long x) { long long i, k; k = (long long)sqrt((double)x) + 1; mr = 0; for (i = 2; i <= k && x != 1; i++) if (x % i == 0) { ++mr; mp[mr] = i; xc[mr] = 1; while (x % i == 0) { x /= i; xc[mr] = xc[mr] * i; } } if (x != 1) { ++mr; mp[mr] = xc[mr] = x; } } long long get_fct(long long x, long long y) { long long ret = 0; while (x != 0) { ret += (x / y); x /= y; } return ret; } long long cnt_exp(long long x, long long y, long long z) { long long ret = 1; while (y != 0) { if (y % 2 == 1) ret = (ret * x) % z; x = (x * x) % z; y = y >> 1; } return ret; } long long extend_gcd(long long a, long long b, long long &x, long long &y, long long z) { long long i, tmp; if (b == 0) { x = 1; y = 0; return a; } i = extend_gcd(b, a % b, x, y, z); tmp = x; x = y; y = (tmp - a / b * y) % z; return i; } long long CRT() { long long i; long long ret = 0; for (i = 1; i <= mr; i++) { long long x, y; extend_gcd(m / xc[i], xc[i], x, y, xc[i]); x = x % m; ret = (ret + xb[i] * m / xc[i] * x) % m; } return (ret + m) % m; } long long reverse(long long a, long long b) { long long x, y; extend_gcd(a, b, x, y, b); return (x % b + b) % b; } long long cnt_c(long long nn, long long mm) { long long i, j, k; divide_factor(m); for (i = 1; i <= mr; i++) { long long fct_num = get_fct(nn, mp[i]) - get_fct(mm, mp[i]) - get_fct(nn - mm, mp[i]); for (j = 2, circle[1] = 1; j < xc[i]; j++) if (j % mp[i] != 0) circle[j] = (circle[j - 1] * j) % xc[i]; else circle[j] = circle[j - 1]; xb[i] = 1; k = nn; while (k != 0) { xb[i] = (xb[i] * ((cnt_exp(circle[xc[i] - 1], k / xc[i], xc[i]) * circle[k - k / xc[i] * xc[i]]) % xc[i])) % xc[i]; k = k / mp[i]; } for (j = 2, circle[1] = 1; j < xc[i]; j++) { if (j % mp[i] != 0) circle[j] = (circle[j - 1] * reverse(j, xc[i])) % xc[i]; else circle[j] = circle[j - 1]; } k = mm; while (k != 0) { xb[i] = (xb[i] * ((cnt_exp(circle[xc[i] - 1], k / xc[i], xc[i]) * circle[k - k / xc[i] * xc[i]]) % xc[i])) % xc[i]; k = k / mp[i]; } k = nn - mm; while (k != 0) { xb[i] = (xb[i] * ((cnt_exp(circle[xc[i] - 1], k / xc[i], xc[i]) * circle[k - k / xc[i] * xc[i]]) % xc[i])) % xc[i]; k = k / mp[i]; } while (fct_num--) xb[i] = (xb[i] * mp[i]) % xc[i]; } return CRT(); } long long cnt_pos(long long x) { long long i, ret; if (x == 0) return 1; x = x % (2 * m); if (x == 0) x = 2 * m; for (i = 2, ret = 0; i <= x; i++) ret = (ret * i + (i % 2 == 0   1 : -1)) % m; return (ret + m) % m; } int main() { int cas, k; scanf(%d, &cas); for (k = 1; k <= cas; k++) { scanf(%lld%lld%lld, &n, &K, &m); long long ans = cnt_c(n, K); ans = (cnt_pos(n - K) * ans) % m; printf(Case %d: %lld , k, ans); } return 0; }