线段树练习
感觉这套题目挺不错的
http://vjudge.net/contest/view.action?cid=50666#overview
做过很多变了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
同上:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
C:HDU 1394Minimum Inversion Number
拿到最初的状态的结果,后面反转的序列都可以递推得到
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
感觉这个提又启发了另一种思路,题义是说每次在下表为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 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
E:POJ 2886Who Gets the Most Candies?
据说是涉及到一个叫反素数的概念 题解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
裸的线段树的区间延时标记
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
G:POJ 3468A Simple Problem with Integers
区间延时标记与查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
W:UVA 11983Weird Advertisement
矩形K次的并,可以作为自己的模板了题解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }