线段树练习

感觉这套题目挺不错的

 

http://vjudge.net/contest/view.action?cid=50666#overview

A:HDU 1166  敌兵布阵

做过很多变了

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 #define INF 1e9
 7 #define inf (-((LL)1<<40))
 8 #define lson k<<1, L, mid
 9 #define rson k<<1|1, mid+1, R
10 #define mem0(a) memset(a,0,sizeof(a))
11 #define mem1(a) memset(a,-1,sizeof(a))
12 #define mem(a, b) memset(a, b, sizeof(a))
13 #define FOPENIN(IN) freopen(IN, "r", stdin)
14 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
15 template<class T> T CMP_MIN(T a, T b) { return a < b; }
16 template<class T> T CMP_MAX(T a, T b) { return a > b; }
17 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
18 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
19 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
20 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
21 
22 typedef __int64 LL;
23 //typedef long long LL;
24 const int MAXN = 50005;
25 const int MAXM = 100005;
26 const double eps = 1e-10;
27 const LL MOD = 1000000007;
28 
29 int T, N;
30 int num[MAXN<<2];
31 int l, r, id, val;
32 
33 void update(int k, int L, int R)
34 {
35     if(L == R){ num[k] += val; return ;}
36 
37     int mid = (L + R) >> 1;
38 
39     if(id <= mid) update(lson);
40 
41     else update(rson);
42 
43     num[k] = num[k<<1] + num[k<<1|1];
44 }
45 
46 int query(int k, int L, int R)
47 {
48     if(R < l || r < L) return 0;
49 
50     if(l<=L && R<=r) return num[k];
51 
52     int mid = (L + R) >> 1;
53 
54     return query(lson) + query(rson);
55 
56 }
57 
58 int main()
59 {
60     scanf("%d", &T);
61     for(int t = 1; t <= T; t ++ )
62     {
63         mem0(num);
64         scanf("%d", &N);
65         for(id=1;id<=N;id++)
66         {
67             scanf("%d%*c", &val);
68             update(1, 1, N);
69         }
70         char str[10];
71         printf("Case %d:\n", t);
72         while(scanf("%s", str) && strcmp(str,"End")!=0)
73         {
74             if(!strcmp(str, "Add")) {
75                 scanf("%d %d%*c", &id, &val);
76                 update(1, 1, N);
77             }
78             else if(!strcmp(str, "Sub")) {
79                 scanf("%d %d%*c", &id, &val);
80                 val=-val; update(1, 1, N);
81             }
82             if(!strcmp(str, "Query")) {
83                 scanf("%d %d%*c", &l, &r);
84                 printf("%d\n", query(1, 1, N));
85             }
86         }
87     }
88     return 0;
89 }
View Code

 

B:HDU 1754I Hate It

同上:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 #define INF 1e9
 7 #define inf (-((LL)1<<40))
 8 #define lson k<<1, L, mid
 9 #define rson k<<1|1, mid+1, R
10 #define mem0(a) memset(a,0,sizeof(a))
11 #define mem1(a) memset(a,-1,sizeof(a))
12 #define mem(a, b) memset(a, b, sizeof(a))
13 #define FOPENIN(IN) freopen(IN, "r", stdin)
14 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
15 template<class T> T CMP_MIN(T a, T b) { return a < b; }
16 template<class T> T CMP_MAX(T a, T b) { return a > b; }
17 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
18 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
19 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
20 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
21 
22 typedef __int64 LL;
23 //typedef long long LL;
24 const int MAXN = 2000005;
25 const int MAXM = 100005;
26 const double eps = 1e-10;
27 const LL MOD = 1000000007;
28 
29 int M, N;
30 int num[MAXN<<2];
31 int l, r, id, val;
32 
33 void update(int k, int L, int R)
34 {
35     if(L == R){ num[k] = val; return ;}
36 
37     int mid = (L + R) >> 1;
38 
39     if(id <= mid) update(lson);
40 
41     else update(rson);
42 
43     num[k] = MAX( num[k<<1], num[k<<1|1]);
44 }
45 
46 int query(int k, int L, int R)
47 {
48     if(R < l || r < L) return -INF;
49 
50     if(l<=L && R<=r) return num[k];
51 
52     int mid = (L + R) >> 1;
53 
54     return MAX( query(lson), query(rson) );
55 
56 }
57 
58 int main()
59 {
60     while(scanf("%d %d", &N, &M) == 2)
61     {
62         mem0(num);
63         for(id=1;id<=N;id++)
64         {
65             scanf("%d%*c", &val);
66             update(1, 1, N);
67         }
68         char ch;
69         for(int i=0;i<M;i++)
70         {
71             scanf("%c", &ch);
72             if(ch == 'U') {
73                 scanf("%d %d%*c", &id, &val);
74                 update(1, 1, N);
75             }
76             if(ch == 'Q') {
77                 scanf("%d %d%*c", &l, &r);
78                 printf("%d\n", query(1, 1, N));
79             }
80         }
81     }
82     return 0;
83 }
View Code

 

C:HDU 1394Minimum Inversion Number

拿到最初的状态的结果,后面反转的序列都可以递推得到

题解

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 1e9
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, mid
18 #define rson k<<1|1, mid+1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FOPENIN(IN) freopen(IN, "r", stdin)
23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
30 
31 typedef __int64 LL;
32 //typedef long long LL;
33 const int MAXN = 5005;
34 const int MAXM = 100005;
35 const double eps = 1e-10;
36 const LL MOD = 1000000007;
37 
38 int c[MAXN], a[MAXN], id[MAXN], N;
39 
40 int lowbit(int x)
41 {
42     return x & (-x);
43 }
44 
45 void update(int k, int x)
46 {
47     while(k <= N)
48     {
49         c[k] += x;
50         k += lowbit(k);
51     }
52 }
53 
54 int getSum(int k)
55 {
56     int sum = 0;
57     while(k > 0)
58     {
59         sum += c[k];
60         k -= lowbit(k);
61     }
62     return sum;
63 }
64 
65 int cmp(int i, int j)
66 {
67     return a[i] > a[j];
68 }
69 
70 int getCnt()
71 {
72     for(int i=1;i<=N;i++) id[i] = i;
73     sort(id+1, id + N + 1, cmp);
74     mem0(c);
75     int cnt = 0;
76     for(int i=1;i<=N;i++)
77     {
78         cnt += getSum(id[i]);
79         update(id[i], 1);
80     }
81     return cnt;
82 }
83 
84 int main()
85 {
86     while(scanf("%d", &N) == 1)
87     {
88         for(int i=1;i<=N;i++) scanf("%d", &a[i]);
89         int ans = getCnt(), x = ans;
90         for(int i=1;i<N;i++)
91         {
92             x = x + N - 2 * a[i] - 1;
93             ans = MIN(ans, x);
94         }
95         printf("%d\n", ans);
96     }
97     return 0;
98 }
View Code

 

D:POJ 2828Buy Tickets

感觉这个提又启发了另一种思路,题义是说每次在下表为a的位置插入一个数B,求最终的整个序列的结果。

树里的每个值表示的是这个区间有多少个空余的位置,这样的话将B插入到A位置就是指B以前需要有A个空余的位置。

只是这里的更新操作里的递归条件不是与mid值比较,而是比较当前插入的这个数所需的空闲位置的数量如左右字节点的数量比较

题解

 1 void update(int k, int L, int R, int x)
 2 {
 3     if(L == R) { pre[k] = r; ans[L] = val; return ; }
 4 
 5     int mid = (L+R)>>1;
 6 
 7     if(x <= pre[k<<1]) update(lson, x);
 8 
 9     else update(rson, x-pre[k<<1]);
10 
11      pre[k] = pre[k<<1] + pre[k<<1|1];
12 }
 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 1e9
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, mid
18 #define rson k<<1|1, mid+1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FOPENIN(IN) freopen(IN, "r", stdin)
23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
30 
31 typedef __int64 LL;
32 //typedef long long LL;
33 const int MAXN = 200005;
34 const int MAXM = 100005;
35 const double eps = 1e-10;
36 const LL MOD = 1000000007;
37 
38 int N, pre[MAXN<<2];
39 int id[MAXN], num[MAXN], ans[MAXN];
40 int r, val;
41 
42 int buildTree(int k, int L, int R)
43 {
44     if(L == R) return pre[k] = 1;
45     int mid = (L+R)>>1;
46     return pre[k] = buildTree(lson) + buildTree(rson);
47 }
48 
49 void update(int k, int L, int R, int x)
50 {
51     if(L == R) { pre[k] = r; ans[L] = val; return ; }
52 
53     int mid = (L+R)>>1;
54 
55     if(x <= pre[k<<1]) update(lson, x);
56 
57     else update(rson, x-pre[k<<1]);
58 
59      pre[k] = pre[k<<1] + pre[k<<1|1];
60 }
61 
62 int main()
63 {
64     while(~scanf("%d", &N))
65     {
66         buildTree(1, 1, N);
67         for(int l=1;l<=N;l++)
68             scanf("%d %d", &id[l], &num[l]);
69         r = 0;
70         for(int i=N;i>0;i--)
71         {
72             val = num[i];
73             update(1, 1, N, id[i] + 1);
74         }
75         for(int i=1;i<=N;i++) printf("%d%c", ans[i], i==N?'\n':' ');
76     }
77     return 0;
78 }
View Code

 

E:POJ 2886Who Gets the Most Candies?

据说是涉及到一个叫反素数的概念  题解

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 1e9
 16 #define inf (-((LL)1<<40))
 17 #define lson k<<1, L, mid
 18 #define rson k<<1|1, mid+1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FOPENIN(IN) freopen(IN, "r", stdin)
 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
 25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
 26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 30 
 31 typedef __int64 LL;
 32 //typedef long long LL;
 33 const int MAXN = 500005;
 34 const int MAXM = 100005;
 35 const double eps = 1e-10;
 36 const LL MOD = 1000000007;
 37 
 38 char name[MAXN][20];
 39 int N, K,cnt, l, r, curPos;
 40 int num[MAXN], tree[MAXN<<2], no[MAXN];
 41 
 42 void buildTree(int k, int L, int R)
 43 {
 44     if(L == R) { tree[k] = 1; return ; }
 45 
 46     int mid = (L + R) >> 1;
 47 
 48     buildTree(lson);  buildTree(rson);
 49 
 50     tree[k] = tree[k<<1] + tree[k<<1|1];
 51 }
 52 
 53 void update(int k, int L, int R, int x)
 54 {
 55     if(L == R) { tree[k] = 0; no[L] = cnt; curPos = L; return ;}
 56 
 57     int mid = (L + R) >> 1;
 58 
 59     if(x <= tree[k<<1]) update(lson, x);
 60 
 61     else update(rson, x-tree[k<<1]);
 62 
 63     tree[k] = tree[k<<1] + tree[k<<1|1];
 64 }
 65 
 66 int query(int k, int L, int R)
 67 {
 68     if(R < l || r < L) return 0;
 69 
 70     if(l<=L && R<=r) return tree[k];
 71 
 72     int mid = (L+R) >> 1;
 73 
 74     return query(lson) + query(rson);
 75 }
 76 
 77 void getNo()
 78 {
 79     cnt = 1; int pos = K;
 80     for(int j=0;j<N-1;j++)
 81     {
 82         update(1, 1, N, pos);
 83         l = 1; r = curPos; int leftNum = query(1, 1, N);
 84         l = curPos; r = N; int rightNum = query(1, 1, N);
 85         int dis = abs(num[curPos]) % (N - cnt);
 86         if(dis == 0) dis = N - cnt;
 87         if(num[curPos] > 0 && rightNum >= dis) pos = leftNum + dis;
 88         else if(num[curPos] >  0 && rightNum <  dis) pos = dis - rightNum;
 89         else if(num[curPos] <  0 && leftNum  >= dis) pos = leftNum - dis + 1;
 90         else if(num[curPos] <  0 && leftNum  <  dis) pos = 2*leftNum + rightNum - dis + 1;
 91         cnt ++;
 92     }
 93     for(int i=1;i<=N;i++)if(!no[i]) no[i] = N;
 94 }
 95 
 96 int isp[MAXN], yue[MAXN], D[MAXN], Max[MAXN];
 97 void init()
 98 {
 99     mem1(isp);yue[1] = 1;
100     for(int i=2;i<MAXN;i++) if(isp[i])
101     {
102         for(int j=2*i;j<MAXN;j+=i)
103         {
104             isp[j] = 0;
105             yue[j] = i;
106         }
107     }
108     D[1] = Max[1] = 1;
109     for(int i=2;i<MAXN;i++)
110     {
111         if(isp[i]) D[i] = 2;
112         else
113         {
114             int last = i / yue[i];
115             int b = 0, n = i;
116             while(n % yue[i] == 0) b ++, n /= yue[i];
117             D[i] = D[last] * (b+1) / b;
118         }
119         if(D[i] > D[Max[i-1]]) Max[i] = i;
120         else Max[i] = Max[i-1];
121     }
122 }
123 
124 int main()
125 {
126     //FOPENIN("in.txt");
127     init();
128     while(~scanf("%d %d%*c", &N, &K))
129     {
130         mem0(tree); mem0(no);
131         buildTree(1, 1, N);
132         for(int i=1;i<=N;i++)
133             scanf("%s %d", name[i], &num[i]);
134         getNo();
135         for(int i=1;i<=N;i++) if(no[i] == Max[N])
136             printf("%s %d\n", name[i], D[Max[N]]);
137     }
138     return 0;
139 }
View Code

 

F:HDU 1698Just a Hook

裸的线段树的区间延时标记

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 1e9
16 #define inf (-((LL)1<<40))
17 #define lson k<<1, L, mid
18 #define rson k<<1|1, mid+1, R
19 #define mem0(a) memset(a,0,sizeof(a))
20 #define mem1(a) memset(a,-1,sizeof(a))
21 #define mem(a, b) memset(a, b, sizeof(a))
22 #define FOPENIN(IN) freopen(IN, "r", stdin)
23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
30 
31 typedef __int64 LL;
32 //typedef long long LL;
33 const int MAXN = 200005;
34 const int MAXM = 100005;
35 const double eps = 1e-10;
36 const LL MOD = 1000000007;
37 
38 int T, N, Q;
39 struct NODE{ LL sum, add; }tree[MAXN<<2];
40 int l, r, add;
41 
42 void updateChild(int k, int L, int R)
43 {
44     if(tree[k].add == 0) return ;
45     int mid = (L + R) >> 1;
46     tree[k].sum = (R-L+1) * tree[k].add;
47     tree[k<<1].add = tree[k].add;
48     tree[k<<1|1].add = tree[k].add;
49     tree[k<<1].sum = tree[k].add * (mid-L+1);
50     tree[k<<1|1].sum = tree[k].add * (R - mid);
51     tree[k].add = 0;
52 }
53 
54 void update(int k, int L, int R)
55 {
56     if(R<l || r<L) return;
57 
58     if(l<=L && R<=r) { tree[k].add = add; tree[k].sum = tree[k].add * (R-L+1); return ; }
59 
60     int mid = (L+R)>>1; updateChild(k, L, R);
61 
62     update(lson);    update(rson);
63 
64     tree[k].sum = tree[k<<1].sum + tree[k<<1|1].sum;
65 }
66 
67 LL query(int k, int L, int R)
68 {
69     if(R<l || r<L) return 0;
70 
71     if(l<=L && R<=r) { return tree[k].sum; }
72 
73     int mid = (L+R)>>1; //updateChild(k, L, R);
74 
75     return query(lson) + query(rson);
76 }
77 
78 int main()
79 {
80     scanf("%d", &T);
81     for(int t = 1; t <= T; t ++ )
82     {
83         mem0(tree);
84         scanf("%d %d", &N, &Q);
85         for(int i=1;i<=N;i++)
86         {
87             l = r = i; add = 1;
88             update(1, 1, N);
89         }
90         for(int i=0;i<Q;i++)
91         {
92             scanf("%d %d %d", &l, &r, &add);
93             update(1, 1, N);
94         }
95         l = 1; r = N;
96         printf("Case %d: The total value of the hook is %I64d.\n", t, query(1, 1, N));
97     }
98     return 0;
99 }
View Code

 

G:POJ 3468A Simple Problem with Integers

区间延时标记与查询

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <cctype>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define INF 0x3f3f3f3f
16 #define mem0(a) memset(a,0,sizeof(a))
17 #define mem1(a) memset(a,-1,sizeof(a))
18 #define lson k<<1, L, mid
19 #define rson k<<1|1, mid+1, R
20 
21 typedef long long LL;
22 const double eps = 1e-12;
23 const int MAXN = 100005;
24 const int MAXM = 500005;
25 
26 struct Node { LL sum, add; } tree[MAXN<<2];
27 int a, b, N, Q;
28 LL c;
29 
30 void updataChild(int k, int L, int R)//将编号为k的标记传到他的子节点去
31 {
32     tree[k].sum += (R-L+1) * tree[k].add;//先更新它自己的sum值
33     tree[k<<1].add += tree[k].add;//将左右子节点的add值更新
34     tree[k<<1|1].add += tree[k].add;
35     tree[k].add = 0;//去掉标记
36 }
37 
38 void update(int k, int L, int R)//更新区间的值
39 {
40     if(R<a || b<L) return ;//不再区间内
41 
42     if(a<=L && R<=b) { tree[k].add += c;  return; }//实际上只更新这个区间的add值
43 
44     int mid = (L+R)>>1;     update(lson);      update(rson); //往左和往右更新
45 
46     tree[k].sum = tree[k<<1].sum + tree[(k<<1)+1].sum//更新当前节点的sum
47                   + (mid-L+1)*tree[k<<1].add + (R-mid)*tree[k<<1|1].add;
48 }
49 
50 LL query(int k, int L, int R)
51 {
52     if(R<a || b<L) return 0;
53 
54     if(a<=L && R<=b) return tree[k].sum + (R-L+1)*tree[k].add;//注意加上当前节点的标记
55 
56     int mid = (L+R)>>1;  updataChild(k, L, R);//吧标记传到子节点
57 
58     return query(lson) + query(rson);
59 }
60 
61 int main()
62 {
63     while(~scanf("%d %d", &N, &Q))
64     {
65         mem0(tree); char ch;
66         for(a=1;a<=N;a++)
67         {
68             scanf("%lld%*c", &c);  b = a;//区间是[a, a]
69             update(1, 1, N);
70         }
71         for(int i=0;i<Q;i++)
72         {
73             scanf("%c", &ch);
74             if(ch == 'Q')
75             {
76                 scanf("%d %d%*c", &a, &b);
77                 printf("%lld\n", query(1,1,N));
78             }
79             else
80             {
81                 scanf("%d %d %lld%*c", &a, &b, &c);
82                 update(1,1,N);
83             }
84         }
85     }
86     return 0;
87 }
View Code

 

W:UVA 11983Weird Advertisement

矩形K次的并,可以作为自己的模板了题解

  1 #include <map>
  2 #include <set>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <vector>
  8 #include <cstdio>
  9 #include <cctype>
 10 #include <cstring>
 11 #include <cstdlib>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 #define INF 1e9
 16 #define inf (-((LL)1<<40))
 17 #define lson k<<1, L, mid
 18 #define rson k<<1|1, mid+1, R
 19 #define mem0(a) memset(a,0,sizeof(a))
 20 #define mem1(a) memset(a,-1,sizeof(a))
 21 #define mem(a, b) memset(a, b, sizeof(a))
 22 #define FOPENIN(IN) freopen(IN, "r", stdin)
 23 #define FOPENOUT(OUT) freopen(OUT, "w", stdout)
 24 template<class T> T CMP_MIN(T a, T b) { return a < b; }
 25 template<class T> T CMP_MAX(T a, T b) { return a > b; }
 26 template<class T> T MAX(T a, T b) { return a > b ? a : b; }
 27 template<class T> T MIN(T a, T b) { return a < b ? a : b; }
 28 template<class T> T GCD(T a, T b) { return b ? GCD(b, a%b) : a; }
 29 template<class T> T LCM(T a, T b) { return a / GCD(a,b) * b;    }
 30 
 31 //typedef __int64 LL;
 32 typedef long long LL;
 33 const int MAXN = 30005;
 34 const int MAXM = 100005;
 35 const double eps = 1e-10;
 36 const int MOD = 9901;
 37 
 38 int N, K, T;
 39 LL Hash[MAXN<<1], cntHash;
 40 int cnt[MAXN<<3], len[MAXN<<3][12];
 41 struct Line {
 42     LL x1, x2, y;
 43     int flag;
 44     Line(){}
 45     Line(LL _x1, LL _x2, LL _y, int _flag)
 46     {
 47         x1 = _x1;
 48         x2 = _x2;
 49         y = _y;
 50         flag = _flag;
 51     }
 52     bool operator < (const Line& A)const
 53     {
 54         if(y != A.y) return y < A.y;
 55         return flag < A.flag;
 56     }
 57 }line[MAXN<<1];
 58 
 59 int bsearch(int low, int high, int num)
 60 {
 61     while(low <= high)
 62     {
 63         int mid = (low + high) >> 1;
 64         if(Hash[mid] == num) return mid;
 65         if(Hash[mid] > num) high = mid - 1;
 66         else low = mid + 1;
 67     }
 68     return 0;
 69 }
 70 
 71 void buildTree(int k, int L, int R)
 72 {
 73     cnt[k] = 0; mem0(len[k]);
 74 
 75     len[k][0] = Hash[R+1] - Hash[L];
 76 
 77     if(L == R) return ;
 78 
 79     int mid = (L + R) >> 1;
 80 
 81     buildTree(lson);    buildTree(rson);
 82 }
 83 
 84 void updateCur(int k, int L, int R)
 85 {
 86     mem0(len[k]);
 87     if(cnt[k] >= K)
 88         len[k][K] = Hash[R+1] - Hash[L];
 89     else if(L == R)
 90         len[k][cnt[k]] = Hash[R+1] - Hash[L];
 91     else {
 92         for(int i=cnt[k];i<=K;i++)
 93             len[k][i] += len[k<<1][i-cnt[k]] + len[k<<1|1][i-cnt[k]];
 94         for(int i=K-cnt[k]+1;i<=K;i++)
 95             len[k][K] += len[k<<1][i] + len[k<<1|1][i];
 96     }
 97 }
 98 
 99 void update(int k, int L, int R, int l, int r, int flag)
100 {
101     if(R < l || r < L) return ;
102 
103     if(l<=L && R<=r) { cnt[k] += flag; updateCur(k, L, R); return ; }
104 
105     int mid = (L + R) >> 1;
106 
107     update(lson, l, r, flag);    update(rson, l, r, flag);
108 
109     updateCur(k, L, R);
110 }
111 
112 void init()
113 {
114     int x1, x2, y1, y2;
115     scanf("%d %d", &N, &K);
116     for(int i=1;i<=N;i++)
117     {
118         scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
119          ++ x2; ++ y2;
120         line[i] = Line(x1, x2, y1, 1);
121         line[i+N] = Line(x1, x2, y2, -1);
122         Hash[i] = x1;
123         Hash[i+N] = x2;
124     }
125     sort(line + 1, line + 2*N + 1);
126 
127     sort(Hash + 1, Hash + 2*N + 1);
128     cntHash = 0;
129     for(int i = 1; i <= N*2; i ++ )
130       if(i==1 || Hash[i-1] != Hash[i])
131         Hash[++cntHash] = Hash[i];
132 
133     buildTree(1, 1, cntHash-1);
134 }
135 
136 int main()
137 {
138     //FOPENIN("in.txt");
139     scanf("%d", &T);
140     for(int t = 1; t <= T; t ++ )
141     {
142         init();
143         LL ans = 0;
144         for(int i = 1; i <= 2 * N; i ++ )
145         {
146             if(i != 1)
147             {
148                 ans += (line[i].y - line[i-1].y) * len[1][K];
149             }
150             int l  = bsearch(1, cntHash, line[i].x1);
151             int r = bsearch(1, cntHash, line[i].x2);
152             update(1, 1, cntHash-1, l, r-1, line[i].flag);
153         }
154 
155         printf("Case %d: %lld\n", t, ans);
156     }
157     return 0;
158 }
View Code

 

posted @ 2014-08-01 11:45  再见~雨泉  阅读(202)  评论(0编辑  收藏  举报