c语言套娃,「JOISC2016」俄罗斯套娃

我们可以把这些套娃抽象成平面直角坐标系里的点(不妨设 R 为横坐标,H 为纵坐标)。

然后我们离线,把每个询问也抽象成这样的点。

然后我们从右下至左上依次加点。

那么我们每次的询问就是询问该点右下区域内的答案。

考虑怎么计算:类似网络流最小割的,我们不难发现,一个区域内点的答案就是这些点可以构成的最长的一条链,满足这条链的形态是从左上到右下的。

可以自己画图理解一下。

然后拿一个树状数组就可以轻松维护了。

参考代码:

#include

#include

using namespace std;

const int _ = 4e5 + 5;

int n, q, x, y, X[_], c[_], ans[_];

struct node { int x, y, id; } t[_];

void update(int x, int v) { while (x < _) c[x] = max(c[x], v), x += x & -x; }

int query(int x) { int res = 0; while (x) res = max(res, c[x]), x -= x & -x; return res; }

int cmp(node a, node b) {

if (a.x != b.x) return a.x > b.x;

if (a.y != b.y) return a.y < b.y;

return a.id < b.id;

}

int main() {

scanf("%d %d", &n, &q);

for (int i = 1; i <= n + q; ++i)

scanf("%d %d", &x, &y), X[++X[0]] = y, t[i] = (node) { x, y, i > n ? i - n : 0 };

sort(t + 1, t + n + q + 1, cmp);

sort(X + 1, X + X[0] + 1);

X[0] = unique(X + 1, X + X[0] + 1) - X - 1;

for (int i = 1; i <= n + q; ++i)

t[i].y = lower_bound(X + 1, X + X[0] + 1, t[i].y) - X;

for (int i = 1; i <= n + q; ++i) {

if (t[i].id)

ans[t[i].id] = query(t[i].y);

else

x = query(t[i].y), update(t[i].y, x + 1);

}

for (int i = 1; i <= q; ++i) printf("%d\n", ans[i]);

return 0;

}

标签:node,JOISC2016,return,int,res,id,套娃,include,俄罗斯

来源: https://www.cnblogs.com/zsbzsb/p/12900816.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值