标签:
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