LightOJ 1372 (枚举 + 树状数组)
2016-05-17 21:14
218 查看
题目
Link输出序列中有多少个组合 {a1,a2,a3,a4,a5,a6}可以构成一个六边形。
分析
序列每个数都不相等。所以可以设 a1<a2<a3<a4<a5<a6。
把六边形分解为 4 个三角形, 又可以得出
a1+a2+a3+a4+a5>a6:
a1+a2+a3>a6−a5−a4。
在 a4 固定的情况下, a3可以取[a3,a4)之间
所以我们枚举 , 用树状数组维护。
Code
#include <bits/stdc++.h> using namespace std; const int maxn = 5000000 + 131; int C[maxn]; int lowbit(int x) { return x &(-x); } int Sum(int x) { int ret = 0; while(x) { ret += C[x]; x -= lowbit(x); } return ret; } void Add(int pos) { while(pos < maxn) { C[pos] ++; pos += lowbit(pos); } } int Num[105]; int main() { int T; scanf("%d",&T); for(int kase = 1; kase <= T; ++kase) { memset(C, 0, sizeof(C)); int N; scanf("%d",&N); for(int i = 0; i < N; ++i) scanf("%d",Num+i); sort(Num, Num+N); int Ans = 0, LowZ = 0; //小于0的情况用LowZ 统计 for(int i = N-1; i >= 0; --i) { for(int j = 0; j < i; ++j) for(int k = j+1; k < i; ++k) { int sum = Num[i] + Num[j] + Num[k]; Ans += Sum(sum-1); Ans += LowZ; } for(int j = i + 1; j < N; ++j) for(int k = j + 1; k < N; ++k) { int sub = Num[k] - Num[j] - Num[i]; if(sub > 0) Add(sub); else LowZ ++; } } printf("Case %d: %d\n",kase, Ans); } return 0; }
相关文章推荐
- LightOJ 1067 Combinations 组合数取模
- Codeforces Coder-Strike 2014 - Finals (online edition, Div. 1)
- HDU 1166 敌兵布阵
- POJ 2352 Stars
- PAT 1057 Stack (30)
- neu 1438 树状数组求逆序数
- poj 2352
- 树状数组
- hdu 4630 No Pain No Game 树状数组
- 树状数组区间求和的三种模型
- LightOJ 1004 - Monkey Banana Problem
- LightOJ 1011 - Marriage Ceremonies
- LightOJ 1033 - Generating Palindromes
- LightOJ 1047 - Neighbor House
- LightOJ 1013 - Love Calculator
- LightOJ 1122 - Digit Count
- LightOJ1112——Curious Robin Hood
- HDOJ1166 敌兵布阵 树状数组
- 二维树状数组
- Hoj 2275 Number Sequence