【HDOJ】3473 Minimum Sum
划分树解。
主席树解MLE。
1 /* 3473 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 #define LL __int64 43 44 const int maxn = 1e5+5; 45 int order[maxn]; 46 int val[18][maxn]; 47 int toLeft[18][maxn]; 48 LL sum[18][maxn]; 49 int n; 50 LL ans; 51 52 void Build(int l, int r, int dep) { 53 if (l == r) { 54 toLeft[dep][l] = toLeft[dep][l-1] + 1; 55 sum[dep][l] = sum[dep][l-1] + val[dep][l]; 56 return ; 57 } 58 59 int mid = (l + r) >> 1; 60 int same = mid - l + 1; 61 rep(i, l, r+1) { 62 if (val[dep][i] < order[mid]) 63 --same; 64 } 65 66 int lpos = l, rpos = mid + 1; 67 rep(i, l, r+1) { 68 if (val[dep][i] < order[mid]) { 69 val[dep+1][lpos++] = val[dep][i]; 70 } else if (val[dep][i]==order[mid] && same>0) { 71 val[dep+1][lpos++] = val[dep][i]; 72 --same; 73 } else { 74 val[dep+1][rpos++] = val[dep][i]; 75 } 76 77 sum[dep][i] = sum[dep][i-1] + val[dep][i]; 78 toLeft[dep][i] = toLeft[dep][l-1] + lpos - l; 79 } 80 81 Build(l, mid, dep+1); 82 Build(mid+1, r, dep+1); 83 } 84 85 int Query(int l, int r, int k, int L, int R, int dep) { 86 if (l == r) 87 return val[dep][l]; 88 89 int mid = (L + R) >> 1; 90 int tmp = toLeft[dep][r] - toLeft[dep][l-1]; 91 92 if (tmp >= k) { 93 int s = mid+1+l-L-(toLeft[dep][l-1] - toLeft[dep][L-1]); 94 int e = mid+r-L+1 - (toLeft[dep][r] - toLeft[dep][L-1]); 95 96 ans += sum[dep+1][e] - sum[dep+1][s-1]; 97 98 int ll = L + toLeft[dep][l-1] - toLeft[dep][L-1]; 99 int rr = ll + tmp - 1; 100 101 return Query(ll, rr, k, L, mid, dep+1); 102 } else { 103 int s = L + toLeft[dep][l-1] - toLeft[dep][L-1]; 104 int e = s + tmp - 1; 105 106 ans -= sum[dep+1][e] - sum[dep+1][s-1]; 107 108 k -= tmp; 109 int rr = r + toLeft[dep][R] - toLeft[dep][r]; 110 int ll = rr - (r-l+1 - tmp) + 1; 111 112 return Query(ll, rr, k, mid+1, R, dep+1); 113 } 114 } 115 116 void solve() { 117 int q; 118 119 sort(order+1, order+1+n); 120 Build(1, n, 0); 121 122 int l, r, kth; 123 int tmp; 124 125 scanf("%d", &q); 126 while (q--) { 127 scanf("%d %d", &l, &r); 128 ++l; 129 ++r; 130 kth = ((l + r) >> 1) - l + 1; 131 ans = 0; 132 tmp = Query(l, r, kth, 1, n, 0); 133 if (((r-l+1) & 1) == 0) 134 ans -= tmp; 135 printf("%I64d\n", ans); 136 } 137 } 138 139 int main() { 140 ios::sync_with_stdio(false); 141 #ifndef ONLINE_JUDGE 142 freopen("data.in", "r", stdin); 143 freopen("data.out", "w", stdout); 144 #endif 145 146 int t; 147 148 scanf("%d", &t); 149 rep(tt, 1, t+1) { 150 scanf("%d", &n); 151 rep(i, 1, n+1) { 152 scanf("%d", &val[0][i]); 153 order[i] = val[0][i]; 154 } 155 printf("Case #%d:\n", tt); 156 solve(); 157 putchar('\n'); 158 } 159 160 #ifndef ONLINE_JUDGE 161 printf("time = %d.\n", (int)clock()); 162 #endif 163 164 return 0; 165 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**5 11 fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = bound 14 q = randint(10, 20) 15 fout.write("%d\n" % (n)) 16 L = [] 17 for i in xrange(n): 18 x = randint(1, bound) 19 L.append(x) 20 fout.write(" ".join(map(str, L)) + "\n") 21 fout.write("%d\n" % (q)) 22 for i in xrange(q): 23 l = randint(0, n-1) 24 r = randint(l, n-1) 25 fout.write("%d %d\n" % (l, r)) 26 27 28 29 def MovDataIn(): 30 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 31 shutil.copyfile("data.in", desFileName) 32 33 34 if __name__ == "__main__": 35 GenDataIn() 36 MovDataIn()