【ZJOI 2013】 K大数查询
? ? · 大神轻虐 ? ? · 真 · 看错题系列 ? ? · 威武的GuyUpLion > <~ ? ? 很久没有更新了...... ? ? 最近很忙的说...每天早上考试就有得受了...还被Delayyy君扯去出题... ? ? ( 其实都是大水题 ) ? ? 前天Noip吧里放出了ZJOI Day 1,正好今早有空就去被虐一下... ? ?? ? ? 原题请去Noip吧里查看... 题目模型转换一下就成了 :维护一个数据结构,支持在一个N*N的矩阵中,每次将一个1 * k 的子矩阵元素值 + 1 ? ? 树套树预订... (其实一开始想分块,不过看着O(Vnlog^2n)的复杂度整个人就虚脱了...) ? ? 第一维度按区间建一直没有想到可行的办法 ( Orz hza,第一维度按区间建 A 了) ? ? 所以考虑按值域建,于是模型很快就出来了. ? ? ? 对于修改操作,第一维度单点修改(c),第二维度区间修改(a,b),时间复杂度 O(log^2n) ? ? 对于询问操作,相当于在第一维度上二分答案,时间复杂度 O(log^2n) ? ? 虽然说空间是O(nlog^2n)的...所以很高兴地敲程序去了... ? ? 但很快就萎成渣一样...N = 38000 节点数就超越了1000w ?(诶?> <~) ? ? 一直无解. ? ?? ? ? 中午突然发现自己第二维度 (区间修改) 用了标记下传,带来了很多冗余的节点.? ? ? 所以就改成标记永久化... A掉了. ? ? 代码非常非常好写... 像我这种代码量通常是别人 200%的 1.6kb就写完了... ? ? 诶你说根本没看懂我在写什么? 看代码就知道了...? ? ? 最后很想知道BZOJ上那些2000+msAC的同学们神一般的思路...哪位大神知道的话还请留言,3q~ #include <cstdio> #include <cstdlib> #include <algorithm> #define mid ((l + r) >> 1) #define son (k << 1) const int ys = 8000010; using namespace std; int n,m,a,x,y,z,ap; int sum[ys],right[ys],left[ys],lazy[ys]; int root[200010]; void add(int &k,int l,int r,int x,int y) { if (x > r || y < l) return; if (!k) k = ++ap; if (x <= l && y >= r) { lazy[k]++; sum[k] += r - l + 1; return; } if (l <= mid) add(left[k],l,mid,y); if (r > mid) add(right[k],mid + 1,r,y); sum[k] = lazy[k] * (r - l + 1) + sum[right[k]] + sum[left[k]]; } int tot(int k,int y) { if (!k) return 0; if (x > r || y < l) return 0; if (x <= l && y >= r) return sum[k]; return tot(right[k],y) + tot(left[k],y) + ((y > r ? r : y) - (x < l ? l : x) + 1) * lazy[k]; } void update(int x,int y,int p) { int l = 1,r = n,k = 1; for (; l != r; ) if (add(root[k],1,n,y),p <= mid) k = son,r = mid; else k = son + 1,l = mid + 1; add(root[k],y); } int ask(int x,k = 1,lap; for (; l != r; ) if ((lap = tot(root[son],y)) >= p) k = son,r = mid; else p -= lap,k = son + 1,l = mid + 1; return mid; } int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); scanf("%d %d",&n,&m); for (int i = 1; i <= m; ++i) { scanf("%d %d %d %d",&a,&x,&y,&z); if (a == 1) { z = n - z + 1; update(x,z); } else printf("%dn",n - ask(x,z) + 1); } }? ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |