DIV1 250pt
题意:有很多袋子,里面装有苹果和橘子(也可能没有),给出每个袋子里有多少个苹果,多少个橘子。如果每个袋子里含有水果的总数都不小于x个,则可以从每个袋子里都拿出x个水果(拿出苹果和橘子的总数为x),将所有拿出的水果混合成一份礼物,问可能混合出的礼物的种数。
最多50个袋子,每个袋子里的苹果和橘子的数量 <= 10^6。
解法:枚举即可,枚举从每个袋子里拿出的水果的数量x,然后求出,拿出总数是x的情况下,苹果最多能拿多少个,最少能拿多少个,相减即可。
至于怎么求最多和最少,由于最多50个袋子,所以暴力即可。比赛的时候我很傻逼地用了更快的递推来求,然后赋值初始化写错了,喜大普奔。。。。。。。。。。
tag:brute-force
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // BEGIN CUT HERE 2 /* 3 4 */ 5 // END CUT HERE 6 #line 7 "WinterAndPresents.cpp" 7 #include <cstdlib> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 #include <vector> 14 #include <iostream> 15 #include <sstream> 16 #include <set> 17 #include <queue> 18 #include <fstream> 19 #include <numeric> 20 #include <iomanip> 21 #include <bitset> 22 #include <list> 23 #include <stdexcept> 24 #include <functional> 25 #include <string> 26 #include <utility> 27 #include <map> 28 #include <ctime> 29 #include <stack> 30 31 using namespace std; 32 33 #define clr0(x) memset(x, 0, sizeof(x)) 34 #define clr1(x) memset(x, -1, sizeof(x)) 35 #define pb push_back 36 #define mp make_pair 37 #define sz(v) ((int)(v).size()) 38 #define out(x) cout<<#x<<":"<<(x)<<endl 39 #define tst(a) cout<<#a<<endl 40 #define CINBEQUICKER std::ios::sync_with_stdio(false) 41 42 typedef vector<int> VI; 43 typedef vector<string> VS; 44 typedef vector<double> VD; 45 typedef long long int64; 46 47 const double eps = 1e-8; 48 const double PI = atan(1.0)*4; 49 const int inf = 2139062143 / 2; 50 51 inline int MyMod( int a , int b ) { return (a%b+b)%b;} 52 53 int num[3000005]; 54 int num2[3000005]; 55 56 int64 max(int x, int64 y) 57 { 58 return x > y ? x : y; 59 } 60 61 class WinterAndPresents 62 { 63 public: 64 long long getNumber(vector <int> an, vector <int> on){ 65 clr0 (num); clr0 (num2); 66 int n = sz(an); 67 for (int i = 0; i < n; ++ i){ 68 ++ num[an[i]]; 69 ++ num2[on[i]]; 70 } 71 int pos = 0; 72 for (int i = 0; i < n; ++ i) 73 if (an[pos] + on[pos] > an[i] + on[i]) pos = i; 74 int64 up = an[pos] + on[pos], cnt = 1; 75 int64 ret = 0, sum = n - num[0], maxx = 0; 76 int64 ts = n - num2[0], minn = 0; 77 while (cnt <= up){ 78 maxx += sum; 79 minn += ts; 80 ret += maxx - max(0, cnt*n-minn) + 1; 81 sum -= num[cnt]; 82 ts -= num2[cnt]; 83 //out (cnt); out (ret); out (sum); out (ts); 84 ++ cnt; 85 } 86 return ret; 87 } 88 89 // BEGIN CUT HERE 90 public: 91 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } 92 //void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0();} 93 private: 94 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); } 95 void verify_case(int Case, const long long &Expected, const long long &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << " Expected: "" << Expected << '"' << endl; cerr << " Received: "" << Received << '"' << endl; } } 96 void test_case_0() { int Arr0[] = {10}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 3LL; verify_case(0, Arg2, getNumber(Arg0, Arg1)); } 97 void test_case_1() { int Arr0[] = {1, 2, 0, 3}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {4, 5, 0, 6}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 0LL; verify_case(1, Arg2, getNumber(Arg0, Arg1)); } 98 void test_case_2() { int Arr0[] = {2, 2, 2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {2, 2, 2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 16LL; verify_case(2, Arg2, getNumber(Arg0, Arg1)); } 99 void test_case_3() { int Arr0[] = {7, 4, 5}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {1, 10, 2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 46LL; verify_case(3, Arg2, getNumber(Arg0, Arg1)); } 100 void test_case_4() { int Arr0[] = {1000000}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arr1[] = {1000000}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); long long Arg2 = 1000002000000LL; verify_case(4, Arg2, getNumber(Arg0, Arg1)); } 101 102 // END CUT HERE 103 104 }; 105 //by plum rain 106 // BEGIN CUT HERE 107 int main() 108 { 109 //freopen( "a.out" , "w" , stdout ); 110 WinterAndPresents ___test; 111 ___test.run_test(-1); 112 return 0; 113 } 114 // END CUT HERE
DIV1 500pt
题意:给出整数n和m,{1,2,3....n}的一个子集a,{1,2,3...m}的一个子集b,要求a和b满足两个条件:1、a和b的元素无交集;2、a中所有元素异或得到的值小于b中所有元素异或得到的值。求这样的集合对(a, b)有多少对。
解法:首先,设a异或的值为x,b异或的值为y,由于x小于y,所以在二进制形式中,一定存在某一位r,在r位之前x和y相同,第r位x为0,y为1。枚举r。
设d[i][j][k]表示前i个数,放进a或b中的所有元素的异或值为j,x第r位为k(0或1)的状态下,一共有多少个这样的集合对。然后只要取d[max(n,m)][t][0]即可,其中t满足的条件是(t >> r) == 1。注意到,本题的两个关键点,一个是用异或值为1表示,前r位x和y相同,第r位不同;另一个是,只要把一个数放进集合a或b都把它和j与一下,然后,因为在比r位高的位a和b两个集合的异或值相同,所以j的这些位异或值为0。
虽然这是一个dp,但是关键的那点还是很难想到的。。。。
tag:dp, think, good
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "WinterAndSnowmen.cpp" 11 #include <sstream> 12 #include <stdexcept> 13 #include <functional> 14 #include <iomanip> 15 #include <numeric> 16 #include <fstream> 17 #include <cctype> 18 #include <iostream> 19 #include <cstdio> 20 #include <vector> 21 #include <cstring> 22 #include <cmath> 23 #include <algorithm> 24 #include <cstdlib> 25 #include <set> 26 #include <queue> 27 #include <bitset> 28 #include <list> 29 #include <string> 30 #include <utility> 31 #include <map> 32 #include <ctime> 33 #include <stack> 34 35 using namespace std; 36 37 #define clr0(x) memset(x, 0, sizeof(x)) 38 #define clr1(x) memset(x, -1, sizeof(x)) 39 #define pb push_back 40 #define sz(v) ((int)(v).size()) 41 #define all(t) t.begin(),t.end() 42 #define zero(x) (((x)>0?(x):-(x))<eps) 43 #define out(x) cout<<#x<<":"<<(x)<<endl 44 #define tst(a) cout<<a<<" " 45 #define tst1(a) cout<<#a<<endl 46 #define CINBEQUICKER std::ios::sync_with_stdio(false) 47 48 typedef vector<int> VI; 49 typedef vector<string> VS; 50 typedef vector<double> VD; 51 typedef pair<int, int> pii; 52 typedef long long int64; 53 54 const double eps = 1e-8; 55 const double PI = atan(1.0)*4; 56 const int inf = 2139062143 / 2; 57 const int mod = 1000000007; 58 59 int n, m; 60 int d[2][2105][2]; 61 62 int gao(int r) 63 { 64 clr0 (d); 65 d[0][0][0] = 1; 66 int cur = 0, tmp = 1 << 11; 67 for (int i = 1; i <= min(n, m); ++ i){ 68 cur ^= 1; 69 int flag = ((i & (1<<r)) > 0); 70 for (int j = 0; j < tmp; ++ j) 71 for (int k = 0; k < 2; ++ k){ 72 d[cur][j][k] = (d[cur^1][j][k] + d[cur^1][j^i][k]) % mod; 73 d[cur][j][k] = (d[cur][j][k] + d[cur^1][j^i][k^flag]) % mod; 74 } 75 } 76 if (n > m) 77 for (int i = m+1; i <= n; ++ i){ 78 cur ^= 1; 79 int flag = ((i & (1<<r)) > 0); 80 for (int j = 0; j < tmp; ++ j) 81 for (int k = 0; k < 2; ++ k) 82 d[cur][j][k] = (d[cur^1][j][k] + d[cur^1][j^i][k^flag]) % mod; 83 } 84 if (n < m) 85 for (int i = n+1; i <= m; ++ i){ 86 cur ^= 1; 87 for (int j = 0; j < tmp; ++ j) 88 for (int k = 0; k < 2; ++ k) 89 d[cur][j][k] = (d[cur^1][j][k] + d[cur^1][j^i][k]) % mod; 90 } 91 int ret = 0; 92 for (int j = 0; j < tmp; ++ j) 93 if ((j >> r) == 1) ret = (ret + d[cur][j][0]) % mod; 94 return ret; 95 } 96 97 class WinterAndSnowmen 98 { 99 public: 100 int getNumber(int N, int M){ 101 n = N; m = M; 102 int ans = 0; 103 for (int i = 0; i < 11; ++ i) 104 ans = (ans + gao(i)) % mod; 105 return ans; 106 } 107 108 // BEGIN CUT HERE 109 public: 110 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } 111 private: 112 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); } 113 void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << " Expected: "" << Expected << '"' << endl; cerr << " Received: "" << Received << '"' << endl; } } 114 void test_case_0() { int Arg0 = 2; int Arg1 = 2; int Arg2 = 4; verify_case(0, Arg2, getNumber(Arg0, Arg1)); } 115 void test_case_1() { int Arg0 = 1; int Arg1 = 1; int Arg2 = 1; verify_case(1, Arg2, getNumber(Arg0, Arg1)); } 116 void test_case_2() { int Arg0 = 3; int Arg1 = 5; int Arg2 = 74; verify_case(2, Arg2, getNumber(Arg0, Arg1)); } 117 void test_case_3() { int Arg0 = 7; int Arg1 = 4; int Arg2 = 216; verify_case(3, Arg2, getNumber(Arg0, Arg1)); } 118 void test_case_4() { int Arg0 = 47; int Arg1 = 74; int Arg2 = 962557390; verify_case(4, Arg2, getNumber(Arg0, Arg1)); } 119 120 // END CUT HERE 121 122 }; 123 124 // BEGIN CUT HERE 125 int main() 126 { 127 // freopen( "a.out" , "w" , stdout ); 128 WinterAndSnowmen ___test; 129 ___test.run_test(-1); 130 return 0; 131 } 132 // END CUT HERE