## 小媛在努力~

P.S. ZXL童鞋的代码比我的短了好多！！！学习之~他的结点存的是slen[i] 覆盖大于等于 i 的次数。这样的话，所有更新一个循环就可以搞定了。

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 60010;
typedef long long LL;

struct Sline{ int x,y1,y2,flag;};
struct Tnode{				// 一维线段树
int l, r, cover, slen[12];
int len() { return r - l;}
int mid() { return MID(l,r);}
bool in(int ll,int rr) { return l >= ll && r <= rr; }
void lr(int ll,int rr){ l = ll; r = rr;}
};

Tnode 	node[MAX<<2];
Sline 	l[MAX];
int 	y[MAX], cnty, cnt, K;

void add_line(int x1,int y1,int x2,int y2,int &cnt)
{
l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt].flag = 1;
y[cnt++] = y1;
l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt].flag = -1;
y[cnt++] = y2;
}

void Build(int t,int l,int r)
{
node[t].lr(l,r);
node[t].cover = 0;
memset(node[t].slen+1, 0, K*sizeof(int));
node[t].slen[0] = y[node[t].r] - y[node[t].l];
if( node[t].len() == 1 )
return ;
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
}

void Updata_len(int t)
{
int cc = node[t].cover;
memset(node[t].slen, 0, (K+1)*sizeof(int));

if( cc >= K )
{
node[t].slen[K] = y[node[t].r] - y[node[t].l];
return ;
}
if( node[t].len() == 1 )
{
node[t].slen[cc] = y[node[t].r] - y[node[t].l];
return ;
}

FOR(i, 0, K+1)
{
int d = i + cc;
if( d >= K ) d = K;
if( d == K )
node[t].slen[d] += (node[L(t)].slen[i] + node[R(t)].slen[i]);
else
node[t].slen[d] = node[L(t)].slen[i] + node[R(t)].slen[i];
}
int sum = 0;
FOR(i, 1, K+1)
sum += node[t].slen[i];

node[t].slen[0] = y[node[t].r] - y[node[t].l] - sum;
}

void Updata(int t, Sline p)
{
if( p.y1 <= y[node[t].l] && p.y2 >= y[node[t].r] )
{
node[t].cover += p.flag;
Updata_len(t);
return ;
}
if( node[t].len() == 1 ) return ;

int mid = node[t].mid();
if( p.y1 < y[mid] )		Updata(L(t), p);
if( p.y2 > y[mid] ) 	Updata(R(t), p);

Updata_len(t);
}
bool cmp(Sline a, Sline b)
{
if( a.x == b.x )
return a.flag > b.flag;
return a.x < b.x;
}

LL solve(int n)
{
LL ans = 0;
sort(y, y+n);
cnty = unique(y, y+n) - y;
sort(l, l+n, cmp);

Build(1, 0, cnty-1);

Updata(1, l[0]);
FOR(i, 1, n)
{
ans += node[1].slen[K] * 1ll * (l[i].x - l[i-1].x);
Updata(1, l[i]);
}
return ans;
}
int main()
{
int ind = 1, ncases, n, x1, y1, x2, y2;

scanf("%d", &ncases);

while( ncases-- )
{
cnt = 0;
scanf("%d%d", &n, &K);

FOR(i, 0, n)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x2++; y2++;
}

if( K > n )
{
printf("Case %d: 0\n", ind++);
continue;
}

LL ans = solve(cnt);

printf("Case %d: %lld\n", ind++, ans);
}

return 0;
}

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)

using namespace std;

const int MAX = 60010;
typedef long long LL;

struct Sline{ int x,y1,y2,flag;};
struct Tnode{				// 一维线段树
int l, r, cover, slen[12];
int len() { return r - l;}
int mid() { return MID(l,r);}
bool in(int ll,int rr) { return l >= ll && r <= rr; }
void lr(int ll,int rr){ l = ll; r = rr;}
};

Tnode 	node[MAX<<2];
Sline 	l[MAX];
int 	y[MAX], cnty, cnt, K;

void add_line(int x1,int y1,int x2,int y2,int &cnt)
{
l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt].flag = 1;
y[cnt++] = y1;
l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt].flag = -1;
y[cnt++] = y2;
}

void Build(int t,int l,int r)
{
node[t].lr(l,r);
node[t].cover = 0;
memset(node[t].slen+1, 0, K*sizeof(int));
//	node[t].slen[0] = y[node[t].r] - y[node[t].l];
if( node[t].len() == 1 )
return ;
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
}

void Updata_len(int t)
{
int cc = node[t].cover;
FOR(i, 0, K+1)
{
if( cc >= i )
node[t].slen[i] = y[node[t].r] - y[node[t].l];
else
if( node[t].len() == 1 )
node[t].slen[i] = 0;
else
node[t].slen[i] = node[L(t)].slen[i-cc] + node[R(t)].slen[i-cc];
}
}

void Updata(int t, Sline p)
{
if( p.y1 <= y[node[t].l] && p.y2 >= y[node[t].r] )
{
node[t].cover += p.flag;
Updata_len(t);
return ;
}
if( node[t].len() == 1 ) return ;

int mid = node[t].mid();
if( p.y1 < y[mid] )		Updata(L(t), p);
if( p.y2 > y[mid] ) 	Updata(R(t), p);

Updata_len(t);
}
bool cmp(Sline a, Sline b)
{
if( a.x == b.x )
return a.flag > b.flag;
return a.x < b.x;
}

LL solve(int n)
{
LL ans = 0;
sort(y, y+n);
cnty = unique(y, y+n) - y;
sort(l, l+n, cmp);

Build(1, 0, cnty-1);

Updata(1, l[0]);
FOR(i, 1, n)
{
ans += node[1].slen[K] * 1ll * (l[i].x - l[i-1].x);
Updata(1, l[i]);
}
return ans;
}
int main()
{
int ind = 1, ncases, n, x1, y1, x2, y2;

scanf("%d", &ncases);

while( ncases-- )
{
cnt = 0;
scanf("%d%d", &n, &K);

FOR(i, 0, n)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x2++; y2++;
}

if( K > n )
{
printf("Case %d: 0\n", ind++);
continue;
}

LL ans = solve(cnt);

printf("Case %d: %lld\n", ind++, ans);
}

return 0;
}


2014-08-03 14:30:50

2014-08-27 16:45:43

2012-11-29 00:32:05

2014-05-05 10:44:10

2015-02-10 18:45:42

2018-02-15 12:46:44

2014-11-27 18:44:06

2014-08-11 19:54:00

2014-10-19 15:38:30