A~
B:我用的枚举两个数字组成的所有数,同时判重bool超内存了,用位压缩才过~
C: 求n个数的一组序列连续从i到j或操作可能得到多少不同的数字。每个数字不超过10^6,即20位。所以或操作本质是向20位二进制的序列填1。
对于每个数ai,枚举每位,向前(0的方向)或。如果该位为0,则向前或过程中其他数该位变化不会由该数引起,此时加入当前数直接退出;
如果该位为1,向前或过程中其他位的变化可以contribute to这一个数,为了避免重复,向前或持续到其左边第一个位数为1的数处。对20位处理完
后,直接输出判重后的结果(判重是相对于20个位之间)。对于同一位不会出现重复加入同一个数字。每个数最多重复20次,所以最多插入集合的次数
为20*n,算法复杂度为O(20 * n)。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <utility> 6 #include <queue> 7 #include <set> 8 #define LL long long 9 10 using namespace std; 11 12 set<int> s; 13 int num[1000001]; 14 int main() 15 { 16 // freopen("in.txt", "r", stdin); 17 int n; 18 while(scanf("%d", &n) == 1) 19 { 20 s.clear(); 21 for(int i = 0, x; i < n; ++i) 22 { 23 scanf("%d", &num[i]); 24 s.insert(num[i]); 25 int nm = num[i]; 26 for(int j = 0; j < 20; ++j) if(num[i] & (1 << j)) 27 { 28 for(int k = i - 1; k >= 0; --k) 29 { 30 if(num[k] & (1 << j)) break; 31 nm |= num[k]; 32 s.insert(nm); 33 } 34 } 35 } 36 printf("%d\n", s.size()); 37 } 38 39 return 0; 40 }
D:感觉水过,枚举每条边,然后我还二分查点了。。各种乱搞。。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <map> 5 #include <utility> 6 #include <queue> 7 #include <vector> 8 #include <set> 9 #define LL long long 10 11 using namespace std; 12 13 int hash[100010]; 14 int first[100010]; 15 int next[200010]; 16 int v[200010]; 17 18 int du[100010]; 19 int ax[110], ay[110], cx, cy; 20 21 int num; 22 void add(int x, int y) 23 { 24 next[num] = first[x]; 25 first[x] = num; 26 v[num++] = y; 27 } 28 29 vector<int> s[100010]; 30 31 int main() 32 { 33 //freopen("in.txt", "r", stdin); 34 int n, m, h, t; 35 while(scanf("%d%d%d%d", &n, &m, &h, &t) == 4) 36 { 37 num = cx = cy = 0; 38 for(int i = 0; i <= n; ++i) s[i].clear(); 39 memset(first, -1, sizeof(first)); 40 memset(hash, 0, sizeof(hash)); 41 memset(du, 0, sizeof(du)); 42 for(int i = 0, x, y; i < m; ++i) 43 { 44 scanf("%d%d", &x, &y); 45 add(x, y), add(y, x); 46 ++du[x], ++du[y]; 47 } 48 int flg = 0; 49 50 for(int i = 1; i <= n; ++i) 51 { 52 for(int e = first[i]; e != -1; e = next[e]) 53 { 54 s[i].push_back(v[e]); 55 } 56 sort(s[i].begin(), s[i].end()); 57 } 58 int ans = -1; 59 for(int e = 0; e < num; ++e) 60 { 61 int cp = 0; 62 if(du[v[e]] > h && du[v[e ^ 1]] > t) 63 { 64 int x = v[e], y = v[e ^ 1]; 65 for(int ee = first[x]; ee != -1; ee = next[ee]) 66 { 67 int ind = lower_bound(s[y].begin(), s[y].end(), v[ee]) - s[y].begin(); 68 if(s[y][ind] == v[ee]) ++cp; 69 } 70 if(du[v[e]] + du[v[e ^ 1]] - cp - 2 >= h + t) 71 { 72 ans = e; 73 flg = 1; 74 break; 75 } 76 } 77 } 78 79 if(flg == 0) 80 { 81 printf("NO\n"); 82 } 83 else 84 { 85 printf("YES\n"); 86 printf("%d %d\n", v[ans], v[ans ^ 1]); 87 for(int e = first[v[ans]]; e != -1; e = next[e]) if(v[e] != v[ans ^ 1]) 88 { 89 hash[v[e]] += 1; 90 } 91 for(int e = first[v[ans ^ 1]]; e != -1; e = next[e]) if(v[e] != v[ans]) 92 { 93 hash[v[e]] += 2; 94 } 95 for(int i = 1; i <= n; ++i) 96 { 97 if(hash[i] == 1 && h) ax[cx++] = i, --h; 98 if(hash[i] == 2 && t) ay[cy++] = i, --t; 99 } 100 for(int i = 1; i <= n; ++i) 101 { 102 if(hash[i] == 3 && h) ax[cx++] = i, --h; 103 else if(hash[i] == 3 && t) ay[cy++] = i, --t; 104 } 105 for(int i = 0; i < cx; ++i) 106 { 107 if(i == 0) printf("%d", ax[i]); 108 else printf(" %d", ax[i]); 109 } 110 printf("\n"); 111 for(int i = 0; i < cy; ++i) 112 { 113 if(i == 0) printf("%d", ay[i]); 114 else printf(" %d", ay[i]); 115 } 116 printf("\n"); 117 } 118 } 119 return 0; 120 }