标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 538 Accepted Submission(s): 259
/*time 62ms
by atrp
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
typedef long long ll;
const int N = 50005;
int a[N];
int n, forc;
ll ans;
int cmp(int a, int b)
{
return (a & (1 << forc)) < (b & (1 << forc));
}
int calc(int low, int high)//寻找排序后a[low。。high - 1]中二进制第forc位不同的分界点,区间为[low,high);
{
int i;
for(i = low; i < high; ++i)
if((a[i] & (1 << forc)) ^ (a[i + 1] & (1 << forc))) break;
if(i == high) return i;
else return i + 1;//注意这里的边界处理
}
void solve(int low, int high)
{
sort(a + low, a + high, cmp);
int m = calc(low, high);
// printf("[%d] - [%d]\n", m, high);
int mi = *min_element(a + low, a + high);
int mx = *max_element(a + low, a + high);
if(mi == mx) return;//当[low,high)中的元素相等时,无需继续递归
forc++;
solve(low, m);
solve(m, high);
forc--;
ans += ((m - low) % 998244353) * ((high - m) % 998244353) * (1 << forc) ;
}
int main()
{
int t, ca = 1;
scanf("%d", &t);
while(t --)
{
scanf("%d", &n);
for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
forc = 0;
ans = 0;
solve(0, n);
printf("Case #%d: %lld\n", ca++,(ans << 1) % 998244353);
}
}
标签:
原文地址:http://www.cnblogs.com/orchidzjl/p/4609707.html