UOJ Logo

NOI.AC

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#199902#2820. 小明的子矩阵Zxc2006111002356ms1480kbC++113.0kb2023-12-24 10:04:302023-12-24 12:15:04

answer

/*
考虑统计关键点小于 k 个的子矩形数量。
枚举上边界,然后从小到大扫下边界,可以维护 c[i] 表示第 i 列的关键点数。
就是对左右边界做双指针,答案即 sum(l) r-l,其中 r 为 [l...r] 的 c 之和不超过 k 的最大 r。
对每个 l 维护 r[l]。c=0 的部分形成一些连续段 [L,R],每段内的 r 等于 R+1 的 r。
维护每个 c>0 的 l 的 r,可以用链表找前后下一个 c>0 的位置。O(N(R+C)k)。
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e9;
int N,M,C,k;
vector<int> rimp[3100];
int c[3100],nxt[3100],pre[3100],rp[3100];
int res;
void twoPointers(int ll,int lr)
{
	for(int l=ll,r=ll,cnt=0;l<=lr;cnt-=c[l],l=nxt[l])
	{
		// cout<<"l="<<l<<" cnt="<<cnt<<endl;
		while(cnt+c[r]<=k)
			cnt+=c[r],r=nxt[r];
		// cout<<"l="<<l<<" r <- "<<r-1<<endl;
		// cout<<"cnt="<<cnt<<" c[r]="<<c[r]<<endl;
		res+=(l-pre[l]-(l==M+1))*((r-1)-rp[l]);
		rp[l]=r-1;
		if(nxt[l]==l)
			break;
	}
}
void build(int U)
{
	// cout<<"Build U="<<U<<endl;
	memset(c,0,sizeof(c));
	memset(nxt,0,sizeof(nxt));
	memset(pre,0,sizeof(pre));
	memset(rp,0,sizeof(rp));

	for(int i=U;i<=N;i++)
	{
		for(int p:rimp[i])
			c[p]+=1;
	}
	c[0]=c[M+1]=inf;
	pre[0]=0,nxt[M+1]=M+1;
	for(int i=1,p=0;i<=M+1;i++)
	{
		if(c[i])
			tie(pre[i],p)=make_pair(p,i);
	}
	for(int i=M,p=M+1;i>=0;i--)
	{
		if(c[i])
			tie(nxt[i],p)=make_pair(p,i);
	}

	// cout<<"c   :";
	// for(int i=0;i<=M+1;i++)
	// 	cout<<" "<<c[i];
	// cout<<endl;
	// cout<<"pre :";
	// for(int i=0;i<=M+1;i++)
	// 	cout<<" "<<pre[i];
	// cout<<endl;
	// cout<<"nxt :";
	// for(int i=0;i<=M+1;i++)
	// 	cout<<" "<<nxt[i];
	// cout<<endl;

	res=0;
	twoPointers(0,M+1);
	res-=(M-1)*M/2;

	// cout<<"rp  :";
	// for(int i=0;i<=M+1;i++)
	// 	cout<<" "<<rp[i];
	// cout<<endl;
}
void decreaseC(int p)
{
	// cout<<"DecC "<<p<<endl;
	if((--c[p])==0)
	{
		res+=(p-pre[p])*(rp[nxt[p]]-rp[p]);
		tie(nxt[pre[p]],pre[nxt[p]])=make_pair(nxt[p],pre[p]);
		tie(pre[p],nxt[p],p)=make_tuple(0,0,pre[p]);
	}
	int lr=p,ll=p;
	for(int i=1;i<=k;i++)
		ll=pre[ll];
	twoPointers(ll,lr);
}
signed main()
{
	cin>>N>>M>>C>>k;
	k--;
	for(int i=1;i<=C;i++)
	{
		int x,y;
		cin>>x>>y;
		rimp[x].push_back(y);
	}
	int ans=0;
	for(int U=1;U<=N;U++)
	{
		build(U);
		for(int D=N;D>=U;D--)
		{
			// cout<<"D="<<D<<" : res="<<res<<endl;
			ans+=res;
			for(int p:rimp[D])
				decreaseC(p);

			// cout<<"c   :";
			// for(int i=0;i<=M+1;i++)
			// 	cout<<" "<<c[i];
			// cout<<endl;
			// cout<<"pre :";
			// for(int i=0;i<=M+1;i++)
			// 	cout<<" "<<pre[i];
			// cout<<endl;
			// cout<<"nxt :";
			// for(int i=0;i<=M+1;i++)
			// 	cout<<" "<<nxt[i];
			// cout<<endl;
			// cout<<"rp  :";
			// for(int i=0;i<=M+1;i++)
			// 	cout<<" "<<rp[i];
			// cout<<endl;
		}
	}
	// cout<<ans<<endl;
	cout<<(N*(N+1)/2)*(M*(M+1)/2)-ans<<'\n';
}
/*
2 2 1 1
1 2

3 2 3 2
1 1
3 1
2 2
*/

详细

小提示:点击横条可展开更详细的信息

Test #1:

score: 5
Accepted
time: 0ms
memory: 1404kb

input:

3 3 3 2
3 1
1 3
2 3

output:

7

result:

ok single line: '7'

Test #2:

score: 5
Accepted
time: 0ms
memory: 1420kb

input:

50 50 50 9
15 14
29 8
5 44
32 41
17 10
11 2
24 30
17 9
3 6
47 26
6 14
35 49
22 7
16 22
11 29
43 45
4...

output:

473085

result:

ok single line: '473085'

Test #3:

score: 5
Accepted
time: 0ms
memory: 1420kb

input:

65 65 66 6
18 41
19 15
38 33
18 39
5 29
1 58
57 56
46 63
49 65
31 32
7 19
30 26
32 36
42 6
39 27
2 6...

output:

2056451

result:

ok single line: '2056451'

Test #4:

score: 5
Accepted
time: 1ms
memory: 1416kb

input:

99 99 99 6
91 69
19 50
76 86
89 64
87 24
30 14
62 49
29 88
82 29
16 98
16 35
6 32
22 56
71 7
91 27
4...

output:

14228380

result:

ok single line: '14228380'

Test #5:

score: 5
Accepted
time: 12ms
memory: 1424kb

input:

494 492 491 8
16 467
375 447
309 397
161 95
332 191
254 1
23 54
415 295
477 351
323 417
74 89
490 26...

output:

11852456124

result:

ok single line: '11852456124'

Test #6:

score: 5
Accepted
time: 40ms
memory: 1436kb

input:

988 996 988 6
90 849
694 694
437 43
19 396
74 496
621 353
217 604
658 13
782 723
469 984
957 151
743...

output:

219099048585

result:

ok single line: '219099048585'

Test #7:

score: 5
Accepted
time: 0ms
memory: 1452kb

input:

3 2964 2950 9
3 910
3 176
2 590
3 553
1 2616
3 1584
3 1085
2 649
3 2926
2 634
3 1666
2 1994
1 2512
3...

output:

26033924

result:

ok single line: '26033924'

Test #8:

score: 5
Accepted
time: 11ms
memory: 1460kb

input:

49 2942 2955 9
6 2349
20 1030
9 349
43 1390
44 957
33 1551
18 1838
13 1535
37 1082
30 688
6 2103
26 ...

output:

5085390486

result:

ok single line: '5085390486'

Test #9:

score: 5
Accepted
time: 10ms
memory: 1468kb

input:

66 2967 2980 5
10 1179
27 1932
47 2903
19 2083
58 787
65 642
25 2464
53 1837
57 2659
45 1919
46 1411...

output:

9500956278

result:

ok single line: '9500956278'

Test #10:

score: 5
Accepted
time: 14ms
memory: 1468kb

input:

98 2946 2976 6
53 1437
56 2741
48 60
12 2871
82 564
69 1198
59 2355
4 191
93 183
65 966
38 2534
92 2...

output:

20381829634

result:

ok single line: '20381829634'

Test #11:

score: 5
Accepted
time: 30ms
memory: 1400kb

input:

2987 2950 2 1
157 924
1311 1509

output:

5265645112770

result:

ok single line: '5265645112770'

Test #12:

score: 5
Accepted
time: 51ms
memory: 1400kb

input:

2945 2994 3 2
852 609
2097 933
2421 1657

output:

1918215338634

result:

ok single line: '1918215338634'

Test #13:

score: 5
Accepted
time: 72ms
memory: 1412kb

input:

2978 2954 50 5
1440 2668
2252 625
2235 1942
1353 2657
2550 659
2136 18
2762 2616
576 1759
1519 2001
...

output:

8309021746649

result:

ok single line: '8309021746649'

Test #14:

score: 5
Accepted
time: 70ms
memory: 1404kb

input:

2971 2953 66 10
648 1597
2113 1742
449 955
1281 635
2779 2737
528 721
2942 2522
367 1306
19 2383
174...

output:

5154520290467

result:

ok single line: '5154520290467'

Test #15:

score: 5
Accepted
time: 78ms
memory: 1412kb

input:

2963 2953 100 6
2757 804
1978 2852
1743 2918
1201 1560
78 1573
1933 1420
191 2142
23 851
1377 2756
1...

output:

10258870225014

result:

ok single line: '10258870225014'

Test #16:

score: 5
Accepted
time: 318ms
memory: 1480kb

input:

2955 2952 2968 1
2094 2680
1844 724
2869 1933
1106 2492
381 411
153 2126
442 1767
2753 401
2870 182
...

output:

18883151797463

result:

ok single line: '18883151797463'

Test #17:

score: 5
Accepted
time: 319ms
memory: 1476kb

input:

2987 2996 2980 1
2275 2213
2902 1155
2415 2885
2570 2581
2767 236
287 12
345 494
1244 315
1203 2139
...

output:

19869585962693

result:

ok single line: '19869585962693'

Test #18:

score: 5
Accepted
time: 318ms
memory: 1480kb

input:

2976 2983 2941 1
2884 2210
2897 2317
2334 1799
2347 658
1366 915
14 231
517 837
2887 2649
2170 287
1...

output:

19551385506236

result:

ok single line: '19551385506236'

Test #19:

score: 5
Accepted
time: 424ms
memory: 1476kb

input:

2982 2960 2946 5
2455 675
2176 375
2975 1690
2791 1591
2361 2275
1890 90
619 1394
1182 633
2596 1388...

output:

18802056193539

result:

ok single line: '18802056193539'

Test #20:

score: 5
Accepted
time: 588ms
memory: 1476kb

input:

2997 2952 2974 9
803 2001
995 1081
1705 2161
675 2271
2393 1620
2609 1647
687 203
2885 2378
1555 873...

output:

18463290975287

result:

ok single line: '18463290975287'