Inna and Binary Logic
2014-03-07 21:59
267 查看
题目链接
题目大意:
给定n个数,相邻两个做与运算,可以得到一行新的数,一直重复下去会只剩最后一个数。然后输入a,b,把原来的a位置的数了、改成b,输出所有数的和
思路:
首先比较直观的方法是用二进制的思路,把每个数的每一位排列开,可以得到n个0、1的排列,然后按照上述规则可以形成一个上小下大的三角形。
观察下图可以发现,对于一个0(红色),可以把整体分成两个独立的三角形,那么可以想到,找到连续的1即可轻易算出这一段形成了几个1
然后在更新的时候,如果发现两个不一样,就需要找到这点左边第一个零和右边第一个零(找与修改点相邻的连续的‘1’段)计算出增加或减少的值
总结:
凡是涉及到位操作的,如^、&和|,都把原来的数分成单个位单独考虑,如此一来对数的操作(在位运算下是没有特点的,很难解题)就变成了对0,1的操作,就可以结合位运算的特点找到相应的规律来结题。
此处注意一下,在判断某一个点处相邻的连续‘1’段时,可以采用set来操作。详细见这篇文章
顺便说一下,在函数传递参数的时候,(下边的findlr函数,如果对大数据结构如数组、set、map等,一定要使用引用,要不会造成效率的很大下降)
题目大意:
给定n个数,相邻两个做与运算,可以得到一行新的数,一直重复下去会只剩最后一个数。然后输入a,b,把原来的a位置的数了、改成b,输出所有数的和
思路:
首先比较直观的方法是用二进制的思路,把每个数的每一位排列开,可以得到n个0、1的排列,然后按照上述规则可以形成一个上小下大的三角形。
观察下图可以发现,对于一个0(红色),可以把整体分成两个独立的三角形,那么可以想到,找到连续的1即可轻易算出这一段形成了几个1
然后在更新的时候,如果发现两个不一样,就需要找到这点左边第一个零和右边第一个零(找与修改点相邻的连续的‘1’段)计算出增加或减少的值
const int MAXN = 110000; int num, kase; int flag[22][MAXN]; LL fun() { LL ret = 0; REP (index, 21) { LL cnt = 0, t = 0; FE(i, 1, num + 1) { if (flag[index][i] == 1) cnt++; else { t += ((cnt * cnt + cnt) >> 1); cnt = 0; } } ret += (1 << index) * t; } return ret; } void findlr(int* f, int n, int& l, int& r) { int i = n - 1; while (f[i] == 1) i--; l = i + 1; i = n + 1; while (f[i] == 1) i++; r = i - 1; } int main() { // freopen("in.txt", "r", stdin); int t, p; while (~RII(num, kase)) { CLR(flag, 0); FE(i, 1, num) { RI(t); REP(ind, 21) { p = (1 << ind); flag[ind][i] = ((t & p) > 0); } } LL ans = fun(); int a, b, l, r; REP(tt, kase) { RII(a, b); REP(ind, 21) { p = (1 << ind); if (((b & p) > 0) != flag[ind][a]) { findlr(flag[ind], a, l, r); LL lenl = a - l, lenr = r - a; ans += (1 - flag[ind][a] * 2) * p * (lenl * lenr + lenl + lenr + 1); flag[ind][a] = !flag[ind][a]; } } cout << ans << endl; } } return 0; }
总结:
凡是涉及到位操作的,如^、&和|,都把原来的数分成单个位单独考虑,如此一来对数的操作(在位运算下是没有特点的,很难解题)就变成了对0,1的操作,就可以结合位运算的特点找到相应的规律来结题。
此处注意一下,在判断某一个点处相邻的连续‘1’段时,可以采用set来操作。详细见这篇文章
顺便说一下,在函数传递参数的时候,(下边的findlr函数,如果对大数据结构如数组、set、map等,一定要使用引用,要不会造成效率的很大下降)
const int MAXN = 110000; template <class T> T abs(T x) { return x < 0 ? -x : x; } int num, kase; int flag[22][MAXN]; set<int> st[22]; set<int>::iterator it; LL fun() { LL ret = 0; REP (index, 21) { LL cnt = 0, t = 0; FE(i, 1, num + 1) { if (flag[index][i] == 1) cnt++; else { t += ((cnt * cnt + cnt) >> 1); cnt = 0; } } ret += (1 << index) * t; } return ret; } void findlr(set<int>& s, int n, int& l, int& r) { s.insert(n); it = s.find(n); it--; l = *it + 1; it++; it++; r = *s.lower_bound(n + 1) - 1; } int main() { // freopen("in.txt", "r", stdin); int t, p; while (~RII(num, kase)) { CLR(flag, 0); REP(i, 21) { FE(j, 0, num + 1) st[i].insert(j); } FE(i, 1, num) { RI(t); REP(ind, 21) { p = (1 << ind); if ((t & p) > 0) { flag[ind][i] = 1; st[ind].erase(i); } else st[ind].insert(i); } } LL ans = fun(); int a, b, l, r; REP(tt, kase) { RII(a, b); REP(ind, 21) { p = (1 << ind); if (((b & p) > 0) != flag[ind][a]) { findlr(st[ind], a, l, r); LL lenl = a - l, lenr = r - a; if (flag[ind][a] == 0) { st[ind].erase(a); ans += p * (lenl * lenr + lenl + lenr + 1); } else { st[ind].insert(a); ans -= p * (lenl * lenr + lenl + lenr + 1); } flag[ind][a] = !flag[ind][a]; } } cout << ans << endl; } } return 0; }
相关文章推荐
- Codeforces 400E Inna and Binary Logic(位运算+暴力)
- Inna and Binary Logic
- CF 400E Inna and Binary Logic(多维线段树)
- !codeforces 400E Inna and Binary Logic-yy-(位运算)
- CodeForces 400E Inna and Binary Logic
- Codeforces400E - Inna and Binary Logic - 思维、数学
- [Leetcode 78] 105 Construct Binary Tree from Preorder and Inorder Traversal
- Leetcode192: Serialize and Deserialize Binary Tree
- [LintCode]Construct Binary Tree from Inorder and Postorder Traversal
- 【construct-binary-tree-from-preorder-and-inorder-traversal】
- 220 DIV2 B. Inna and Nine
- Construct Binary Tree from Inorder and Postorder Traversal -- LeetCode
- 泛型Binary Search Tree实现,And和STL map比较的经营业绩
- 【LeetCode】105. Construct Binary Tree from Preorder and Inorder Traversal
- 105. Construct Binary Tree from Preorder and Inorder Traversal
- Binary Coded Ternary and Its Inverse
- Xml/Binary SerializerHelper and XmlReader read xml node/attribute on foward-only sequential
- Codeforces Round #229 (Div. 2)B. Inna, Dima and Song
- 106. Construct Binary Tree from Inorder and Postorder Traversal
- Leetcode: Construct Binary Tree from Preorder and Inorder Traversal