加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

【ZJOI 2013】 K大数查询

发布时间:2020-12-14 04:12:56 所属栏目:大数据 来源:网络整理
导读:? ? · 大神轻虐 ? ? · 真 · 看错题系列 ? ? · 威武的GuyUpLion ~ ? ? 很久没有更新了...... ? ? 最近很忙的说...每天早上考试就有得受了...还被Delayyy君扯去出题... ? ? ( 其实都是大水题 ) ? ? 前天Noip吧里放出了ZJOI Day 1,正好今早有空就去被虐一下

? ? · 大神轻虐

? ? · 真 · 看错题系列

? ? · 威武的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);
  }
}
? ?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读