Ad Infinitum 8 - Math Programming Contest

比赛链接

A题

如果当前数是1,那么后面无论是几都会加1或者当后面数是1的时候加2,所以记录一下后面的数中1的个数(加2)即可。

如果当前数是2,那么只有当后面的数为1或者为2时才可以加1,所以再记录一下后面数中2的个数即可。

 1 #include <map>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 int a[200050], t, n, num1[200050], num2[200050];
11 
12 int main() {
13     ios::sync_with_stdio(false);
14     cin >> t;
15     while (t--) {
16         cin >> n;
17         for (int i = 1; i <= n; i++) cin >> a[i];
18         memset(num1, 0, sizeof(num1));
19         memset(num2, 0, sizeof(num2));
20         for (int i = n; i >= 1; i--) {
21             num1[i] = num1[i + 1];
22             num2[i] = num2[i + 1];
23             if (a[i] == 1) num1[i]++;
24             else if (a[i] == 2) num2[i]++;
25         }
26         long long res = 0;
27         for (int i = 1; i <= n; i++) {
28             if (a[i] == 1) {
29                 res += n - i + num1[i + 1];
30             } else if (a[i] == 2) {
31                 res += num1[i + 1] + num2[i + 1];
32             } else {
33                 res += num1[i + 1];
34             }
35         }
36         cout << res << endl;
37     }
38     return 0;
39 }

B题

这题需要敏锐的洞察力啊,起码对我来说是这样!

手动向后推两项就可以发现,当N为2时,S = (a1 + 1) * (a2 + 1) - 1; 

当N为3时,S = (a1 + 1) * (a2 + 1) * (a3 + 1) - 1

可以发现,一个序列的S值和其顺序无关,只和数有关。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int MOD = 1e9 + 7;
 9 const int MAX_N = 10050;
10 const int MAX_V = 1000050; 
11 typedef long long LL;
12 #define rep(i, n) for (int i = (1); i <= (n); i++)
13 
14 int main() {
15     ios::sync_with_stdio(false);
16     int N;
17     LL res = 0;
18     cin >> N;
19     rep (i, N) {
20         int x;
21         cin >> x;
22         res = (res + x + res * x) % MOD;
23     }
24     cout << res << endl;
25     return 0;
26 }

C题

很裸的求逆,快速幂。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 int extgcd(int a, int b, int &x, int &y) {
 9     int d = a;
10     if (b != 0) {
11         d = extgcd(b, a % b, y, x);
12         y -= (a / b) * x;
13     } else {
14         x = 1; y = 0;
15     }
16     return d;
17 }
18 
19 int mod_inverse(int a, int m) {
20     int x, y;
21     extgcd(a, m, x, y);
22     return (m + x % m) % m;
23 }
24 
25 int mod_pow(int a, int b, int m) {
26     long long res = 1;
27     while (b) {
28         if (b & 1) res = res * a % m;
29         a = ((long long)a * a) % m;
30         b >>= 1;
31     }
32     return res;
33 }
34 
35 int main() {
36     ios::sync_with_stdio(false);
37     int t;
38     cin >> t;
39     while (t--) {
40         int a, b, x;
41         cin >> a >> b >> x;
42         if (b < 0) {
43             a = mod_inverse(a, x);
44             b = -b;
45         }
46         cout << mod_pow(a, b, x) << endl;
47     }
48     return 0;
49 }

D题

容斥原理模板题

 1 #include <map>
 2 #include <cmath>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 typedef long long LL;
11 const int MAX_N = 20;
12 int N;
13 int num[MAX_N];
14 LL n, ans;
15 LL gcd(LL a, LL b){
16     LL r;
17     while( b ){
18         r = a%b;
19         a = b;
20         b = r;
21     }
22     return a;
23 }
24 
25 void dfs( int id, LL Lcm, bool flag ){
26     Lcm = Lcm*num[ id ] / gcd( Lcm,num[ id ] );
27     if( flag ) ans += n/Lcm;
28     else ans -= n/Lcm;
29     for( int i=id+1;i<= N;i++ ){
30         dfs( i,Lcm,!flag );
31     }
32     return;
33 }
34 
35 int main() {
36     ios::sync_with_stdio(false);
37     cin >> N;
38     for (int i = 1; i <= N; i++) cin >> num[i];
39     int D;
40     cin >> D;
41     for (int i = 1; i <= D; i++) {
42         LL l, r;
43         cin >> l >> r;
44         LL ansr = 0, ansl = 0;
45         ans = 0;
46         n = r;
47         for (int i = 1; i <= N; i++) dfs(i, num[i], true);
48         ansr = ans;
49         ans = 0;
50         n = l - 1;
51         for (int i = 1; i <= N; i++) dfs(i, num[i], true);
52         ansl = ans;
53         cout << ansr - ansl << endl;
54     }
55     return 0;
56 }

E题

从难度来看这题算是简单的规律题。。可是比赛中却没敢去写。

通过数列的前几项可以很自然的和fib数联系在一起。我们需要做的就是统计每个二进制位上的值。

通过本题学习了bitset的使用,很好用,支持两个bitset间进行位运算,很方便。

 1 #include <cmath>
 2 #include <bitset>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <iostream>
 6 #include <algorithm>
 7 using namespace std;
 8 
 9 const int MOD = 1e9 + 7;
10 const int MAX_N = 500050;
11 typedef long long LL;
12 #define rep(i, n) for (int i = (1); i <= (n); i++)
13 const int NUM = 100;
14 LL fib[NUM], sum[NUM];
15 
16 LL mod_pow(LL a, LL b) {
17     LL res = 1;
18     while (b) {
19         if (b & 1) res = (res * a) % MOD;
20         a = (a * a) % MOD;
21         b >>= 1;
22     }
23     return res;
24 }
25 
26 bitset<NUM> solve(LL x) {
27     bitset<NUM> res;
28     while (x) {
29         int pos = upper_bound(sum, sum + NUM, x) - sum - 1;
30         x -= sum[pos];
31         res.set(pos);
32     }
33     return res;
34 }
35 
36 int main() {
37     fib[0] = 0; fib[1] = 1;
38     sum[0] = 1; sum[1] = 2;  
39     for (int i = 2; i < NUM; i++) {
40         fib[i] = fib[i - 2] + fib[i - 1];
41         sum[i] = sum[i - 1] + fib[i];
42     }
43     
44     ios_base::sync_with_stdio(false);
45     int N;
46     cin >> N;
47     bitset<NUM> res;
48     rep (i, N) {
49         LL x;
50         cin >> x;
51         res ^= solve(x);
52     }
53     LL ans = 0;
54     for (int i = 0; i < res.size(); i++) if (res.test(i)) ans = (ans + mod_pow(2, i)) % MOD;
55     cout << ans << endl;
56     return 0;
57 }

F题

待续。。

G题

待续。。

H题

待续。。

posted on 2014-10-20 16:25  Stomach_ache  阅读(156)  评论(0编辑  收藏  举报

导航