【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()

 

你可能感兴趣的:(【HDOJ】3473 Minimum Sum)