题意
给定一个R∗C的矩阵,一开始每个位置都是0。然后有N个特殊的位置
数据范围
K≤min(N,10)
题解
首先,一个矩阵可以由两个二元组(x,x1),(y,y1)表示x的范围以及
考虑一种比较暴力的做法,对于当前的(x,x1),提取出所有在这个范围内的1,并把他们按
这种做法对于每个
我们先对于(x,R)做一下这个算法,然后我们就可以得到ki,以及每个1的前驱与后驱。接着从
最后总的复杂度就是O(R2+R∗N∗K)。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 3005;
typedef long long LL;
struct Node
{
int x,y;
}Po[MAXN];
vector<int> All[MAXN],Lk[MAXN];
int R,C,N,K;
int Pre[MAXN],Next[MAXN];
int main()
{
//freopen("data.in","r",stdin),freopen("data.out","w",stdout);
scanf("%d%d%d%d", &R, &C, &N, &K);
for(int i = 1;i <= N;i ++)
{
scanf("%d%d", &Po[i].x, &Po[i].y);
All[Po[i].x].push_back(i);
Lk[Po[i].y].push_back(i);
}
Po[N + 1].y = C + 1;
LL ans = 0;
for(int i = 1;i <= R;i ++)
{
static int Cur[MAXN],S[MAXN];
int tot = 0;
for(int j = 1;j <= C;j ++)
for(int k = 0;k < Lk[j].size();k ++)
if (Po[Lk[j][k]].x >= i) Cur[++ tot] = Lk[j][k];
Cur[tot + 1] = N + 1;
LL cur = 0;
for(int j = 1;j <= tot;j ++)
{
Pre[Cur[j]] = Cur[j - 1],Next[Cur[j]] = Cur[j + 1];
if (j + K - 1 <= tot) S[Cur[j]] = Cur[j + K - 1]; else
S[Cur[j]] = Cur[tot + 1];
cur += (C - Po[S[Cur[j]]].y + 1) * 1ll * (Po[Cur[j]].y - Po[Cur[j - 1]].y);
}
ans += cur;
for(int j = R;j >= i;j --)
{
for(int k = 0;k < All[j].size();k ++)
{
int ref = All[j][k];
int p = Next[ref];
if (p != N + 1) cur -= (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
Pre[Next[ref]] = Pre[ref],Next[Pre[ref]] = Next[ref];
if (p != N + 1) cur += (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
if (S[ref] != N + 1)
{
cur -= (C - Po[S[ref]].y + 1) * 1ll * (Po[ref].y - Po[Pre[ref]].y);
for(int p = Pre[ref],c = K - 1;p && c;p = Pre[p],c --)
{
cur -= (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
S[p] = Next[S[p]];
cur += (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
}
} else
{
tot = 0;
for(int p = Next[ref];p;p = Next[p]) Cur[++ tot] = p;
reverse(Cur + 1,Cur + tot + 1);
for(int p = Pre[ref],c = K - 1;p && c;p = Pre[p],c --)
{
cur -= (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
Cur[++ tot] = p;
if (tot - K + 1 > 0) S[p] = Cur[tot - K + 1]; else S[p] = N + 1;
cur += (C - Po[S[p]].y + 1) * 1ll * (Po[p].y - Po[Pre[p]].y);
}
}
}
ans += cur;
}
}
printf("%I64d\n", ans);
return 0;
}