1372 - Hexagonal Bamboo Fort 树状数组
给一个序列,查询可以组成6边形的选择方式。
思路:
组成条件是\(a_1<a_2<a_3<a_4<a_5<a_6 \,\, AND\,\, a_1+a_2+a_3+a_4+a_5 > a_6\)
想过优化\(a_1+a_2+a_3 > a_6-a_5-a_4\),枚举\(a_3\)或者\(a_4\),但是这样仍是O(\(n^4\)),仍是不行的。
参考了别人的方法,对于\(a_3\)和\(a_4\)的选择,只需要选择一个,另一个的范围就已经确定了,这样就变成O(\(n^3\)).
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <stack>
#include <string>
#include <math.h>
#include <bitset>
#include <ctype.h>
using namespace std;
typedef pair<int,int> P;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-9;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
int n,t,kase=0;
int c[N],a[N];
inline int lowbit(int x)
{
return x&(-x);
}
void add(int x, int val)
{
while(x < N)
{
c[x] += val;
x += lowbit(x);
}
}
int sum(int x)
{
int sum = 0;
while(x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
int main()
{
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a, a+n);
memset(c, 0, sizeof(c));
LL ans = 0;
for(int k = n-1; k >= 0; k--)
{
for(int i = 0; i < k; i++)
{
for(int j = i+1; j < k; j++)
{
int tmp = a[i]+a[j]+a[k];
ans += sum(tmp-1);
}
}
for(int i = k+1; i < n; i++)
{
for(int j = i+1; j < n; j++)
{
int tmp = a[j]-a[i]-a[k];
if(tmp <= 0) tmp = 1;
add(tmp, 1);
}
}
}
printf("Case %d: %lld\n", ++kase, ans);
}
return 0;
}
如果有错误,请指出,谢谢