srm 565 div2
1、水题,简单的画图,略过。
2、用到了贪心算法,需要把当前n个金币可以买到的最强能力保存下来,然后在可以达到终点的路径中取最小的即可。
 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <map>
 7 #include <stack>
 8 #include <algorithm>
 9 #include <list>
10 #include <ctime>
11 #include <set>
12 #include <queue>
13 using namespace std;
14 
15 typedef long long ll;
16 ll pricepower[30][50];
17 class MonstersValley2 {
18 public:
19     int minimumPrice(vector<int> dread, vector<int> price) {
20         int dsz = dread.size();
21         pricepower[0][price[0]] = dread[0];
22         for (int i = 1; i < dsz; i++) {
23             for (int j = 45; j >= -1; j--) {
24                 if (pricepower[i - 1][j] >= dread[i]) {
25                     pricepower[i][j] = pricepower[i - 1][j];
26                 }
27             }
28 
29             for (int j = 45; j >= -1; j--) {
30                 if (pricepower[i-1][j]!=0) {
31                     pricepower[i][j+price[i]] = max(pricepower[i][j+price[i]],pricepower[i - 1][j]+dread[i]);
32                 }
33             }
34         }
35         int res=0;
36         for (int i = 0; i < 45; i++) {
37             if(pricepower[dsz-1][i]!=0){
38                 res=i;
39                 break;
40             }
41         }
42         return res;
43     }
44 
45 };
3、刚开始想到的办法是因子a到N的路径,时间复杂度太高了,N的因子个数是n,时间复杂度是O(H*n^2),后来发现矩阵相乘的时候可以优化,但是n的复杂度又上去了,达到O(log(H)*n^3)(下边),超过了两秒,还是不行。
  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <cstdlib>
  5 #include <map>
  6 #include <algorithm>
  7 #include <stack>
  8 #include <queue>
  9 #include <cmath>
 10 using namespace std;
 11 const int mool = 1000000009;
 12 typedef long long ll;
 13 typedef vector<vector<int> > vvint;
 14 typedef map<int, int>::iterator it_int_int;
 15 typedef map<int, int> mii;
 16 map<int, int> allmap;
 17 class DivisibleSequence {
 18 public:
 19     int count(int N, int H) {
 20         if (H == 1)
 21             return 1;
 22         int half = sqrt(N) + 10;
 23         cout << half << endl;
 24         int cur = N;
 25         vector<int> div;
 26         div.push_back(1);
 27         div.push_back(N);
 28         for (int i = 2; i < half; i++) {
 29             if ((cur % i) == 0) {
 30                 while (1) {
 31                     div.push_back(i);
 32                     cur = cur / i;
 33                     if ((cur % i) != 0)
 34                         break;
 35                 }
 36             }
 37         }
 38         if (cur != 1 && cur != N)
 39             div.push_back(cur);
 40         map<int, int> num_c;
 41         for (int i = 0; i < div.size(); i++)
 42             num_c[div[i]]++;
 43         map<int, int> num_next;
 44         num_next = num_c;
 45         for (it_int_int j = num_next.begin(); num_next.end() != j; j++) {
 46             j->second = 1;
 47         }
 48         while (1) {
 49             bool judge = true;
 50             for (it_int_int i = num_c.begin(); num_c.end() != i; i++) {
 51                 for (it_int_int j = num_next.begin(); num_next.end() != j;
 52                         j++) {
 53                     ll cnum = j->first;
 54                     ll mul = (i->first) * cnum;
 55                     if ((N % mul) == 0) {
 56                         it_int_int ittmp = num_next.find(mul);
 57                         if (num_next.end() == ittmp) {
 58                             judge = false;
 59                             num_next[mul] = 1;
 60                         }
 61                     }
 62                 }
 63             }
 64             if (judge)
 65                 break;
 66         }
 67 
 68         int tmpkaka = 0;
 69         for (it_int_int j = num_next.begin(); num_next.end() != j; j++) {
 70             allmap[tmpkaka] = j->first;
 71             cout << allmap[tmpkaka] << endl;
 72             tmpkaka++;
 73         }
 74         int nsz = num_next.size();
 75         cout << nsz << endl;
 76         vector<vector<int> > allzero(nsz, vector<int>(nsz, 0));
 77 
 78         vvint pow = allzero;
 79         int i1 = 0;
 80         for (it_int_int i = num_next.begin(); num_next.end() != i; i++) {
 81             int cur_nm1 = i->first;
 82             int j1 = 0;
 83             for (it_int_int j = num_next.begin(); num_next.end() != j; j++) {
 84                 int cur_nm = j->first;
 85                 if ((cur_nm % cur_nm1) == 0) {
 86                     ll tmp = (pow[i1][j1] + i->second) % mool;
 87                     pow[i1][j1] = tmp;
 88                 }
 89                 j1++;
 90             }
 91             i1++;
 92         }
 93 
 94         vvint a, c, res;
 95         a = pow;
 96         res = allzero;
 97         for (int i = 0; i < nsz; i++) {
 98             res[i][i] = 1;
 99         }
100         int counter = H - 1;
101         int kaka = 0;
102         while (counter) {
103             cout << kaka << endl;
104             int remain = counter % 2;
105             cout << "here2\n";
106             if (remain == 1) {
107                 multi(pow, res, res);
108             }
109             cout << "here\n";
110             counter /= 2;
111             multi(a, a, pow);
112 
113             cout << "here1\n";
114             a = pow;
115             kaka++;
116         }
117         int finalres = 0;
118         for (int i = 0; i < nsz; i++) {
119             finalres = (finalres + res[i][nsz - 1]) % mool;
120         }
121         return finalres;
122     }
123     void multi(vvint& a, vvint b, vvint &c) {
124         int asz = a.size();
125         for (int i = 0; i < asz; i++) {
126             for (int j = i; j < asz; j++) {
127                 if ((allmap[j] % allmap[i]) == 0) {
128                     c[i][j] = 0;
129                     for (int k = i; k < j + 1; k++) {
130                         if (a[i][k] != 0 && b[k][j] != 0) {
131                             ll tmp1 = a[i][k];
132                             ll tmp2 = b[k][j];
133                             ll tmp3 = c[i][j];
134                             ll curval = (tmp3 + tmp1 * tmp2) % mool;
135                             c[i][j] = curval;
136                         }
137                     }
138                 }
139             }
140         }
141     }
142 };
今天看了看wiki,终于知道怎么办了,还是数学功底要深厚啊,费马小定理啊~~~泪奔,实在想不到
 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <cstdlib>
 5 #include <map>
 6 #include <algorithm>
 7 #include <stack>
 8 #include <queue>
 9 #include <cmath>
10 using namespace std;
11 
12 typedef long long ll;
13 const ll mod = 1000000009;
14 
15 class DivisibleSequence {
16 public:
17     ll modPow(ll x, ll y) { //计算x的y次方
18         ll r = 1, a = x;
19         while (y > 0) {
20             if ((y & 1) == 1) {
21                 r = (r * a) % mod;
22             }
23             a = (a * a) % mod;
24             y /= 2;
25         }
26         return r;
27     }
28     ll modInverse(ll x) {
29         //计算x',使得 x * x' =1 (模 mod),mod是质数,可知  x * (x^(mod-2)) =1 (模 mod)
30         //可得x'=(x^(mod-2)) (模 mod)
31         return modPow(x, mod - 2);
32     }
33 
34     ll modDivision(ll p, ll q) {
35         //若想计算  x/y (模mod),等价于计算  x*y' (模mod)
36         return (p * modInverse(q)) % mod;
37     }
38 
39     ll C(ll n, int k) { //计算C(n,k)
40         if (k > n) {
41             return 0;
42         }
43         ll p = 1, q = 1;
44         for (int i = 1; i <= k; i++) {
45             q = (q * i) % mod;
46             p = (p * (n - i + 1)) % mod;
47         }
48         return modDivision(p, q);
49     }
50     int count(int N, int H) {
51         ll res = 1;
52         //获取质因子p以及它的幂c
53         for (int p = 2; p <= N / p; p++) {
54             int c = 0;
55             while (N % p == 0) {
56                 N /= p;
57                 c++;
58             }
59             res = (res * C(H - 1 + c, c)) % mod;
60         }
61 
62         if (N > 1) {//如果还剩下一个质数因子
63             res = (res * C(H, 1)) % mod;
64         }
65         return (int) res;
66     }
67 };
div1-2
nim游戏的变种,同构映射加速部分蛮有意思。
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <cstdlib> 5 #include <map> 6 #include <algorithm> 7 #include <stack> 8 #include <queue> 9 #include <cmath> 10 using namespace std; 11 12 typedef long long ll; 13 typedef vector<int> vi; 14 typedef vector<long long> vll; 15 const ll mod = 1000000009; 16 class TheDivisionGame { 17 public: 18 ll countWinningIntervals(int L, int R) { 19 int n = R - L + 1; 20 // Find the list of n counts of prime factors: 21 vi nimber(n); 22 vi current(n); 23 for (int i = L; i <= R; i++) { 24 current[i - L] = i; 25 } 26 // A modified Sieve of Erathostenes: 27 for (int p = 2; p <= R / p; p++) { 28 int s = L; 29 if (L % p != 0) { 30 s += p - (L % p); 31 } 32 while (s <= R) { 33 while (current[s - L] % p == 0) { 34 current[s - L] /= p; 35 nimber[s - L]++; 36 } 37 s += p; 38 } 39 } 40 for (int i = L; i <= R; i++) { 41 if (current[i - L] != 1) { 42 nimber[i - L]++; 43 } 44 } 45 for (int i = L; i <= R; i++) { 46 cout << nimber[i - L] << " "; 47 } 48 cout << endl; 49 50 // Counting the number of consecutive subsequences with a xor different 51 // to 0. 52 ll s = 0; //We will first count the ones with a xor equal to 0: 53 54 // The following two codes are equivalent. Can you tell why? 55 // #1: 56 vll next(32); 57 for (int i = n - 1; i >= 0; i--) { 58 vll curr(32); 59 for (int x = 0; x < 32; x++) { 60 curr[nimber[i] ^ x] = next[x]; //等价于curr[x] = next[nimber[i] ^x]; 61 } //1 62 curr[nimber[i]]++; //2 63 s += curr[0]; 64 next = curr; 65 } 66 67 //方法1.5 68 // vll origin(32); 69 // ll fmap = nimber[n - 1]; 70 // for (int i = n - 1; i >= 0; i--) { 71 // origin[0 ^ fmap]++; 72 // fmap ^= nimber[i]; 73 // s += origin[fmap]; 74 // } 75 76 //方法2 77 /* ll dp(32, 0); 78 int x = 0; 79 for (int i = n - 1; i >= 0; i--) { 80 dp[x]++; 81 x ^= nimber[i]; 82 s += dp[x]; 83 }*/ 84 85 return (n + 1) * (ll) n / 2 - s; 86 } 87 };
 
                    
                 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号