题目1:https://ac.nowcoder.com/acm/contest/12479/E谁是天选之人
我的代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=46936115
题目2:https://ac.nowcoder.com/acm/contest/9984/G九峰与蛇形填数
我的代码:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=46884615
总结:这种,某区间插入,先插入的后面就不能插入了。可以缩小区间:每次[l,r]从r到l插入,每个数赋值nxt[l]=r,而且如果nxt[nxt[l]]!=0,nxt[l]=nxt[nxt[l]](倍增)。
//复杂度大概由O(nlogm)降到O(n+m)
代码:
一维(题目1):
per(j, r, l) {
if (lst[j]) {
if (lst[lst[j]]) lst[j] = lst[lst[j]];
j = lst[j];
} else {
lst[j] = l;
if (lst[l]) lst[j] = lst[l];
ans[j] = i;
}
}
二维(题目2):
void ins(ll x, ll y, ll k)
{
rep(i, x, x + k - 1)
{
rep(j, y, y + k - 1)
{
if (a[i][j] == 0)
{
ll nx = i - x, ny = j - y + 1;
a[i][j] = nx * k;
if (nx % 2 == 0)
a[i][j] += ny;
else
a[i][j] += (k - ny + 1);
nxtj[i][j] = y + k;
//?这是哪位大佬操作的?之前也有这样的想法,但就是不敢取操作。记住一种关于数组的解题思路:离散化j(记住下一个还没有赋值的j)
}
else
j = nxtj[i][j]-1;
/*
ll a = i - s[tmp].x, b = j - s[tmp].y + 1;
if (a % 2 == 0)
print(a * s[tmp].k + b, ' ');
else
print(a * s[tmp].k + s[tmp].k - b + 1, ' ');*/
}
}
}