ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

酒馆的聒噪怪

2021-10-09 15:33:39  阅读:150  来源: 互联网

标签:le int 酒馆 qr Build ql 聒噪


前言

二十分钟rush了个树套树,十分钟把锅调出来,结果空间炸了,这不写篇题解纪念一下?

这 T4 不A也罢。

题目

聒噪怪又泛滥成灾了。

经过多代杂交,聒噪怪们变异出了不同的种类,产生了生殖隔离。没有人会喜欢聒噪怪,除了聒噪怪们本身。现在酒馆里出现了 \(n\times m\) 个聒噪怪,第 \(i\) 行 \(j\) 列的聒噪怪的种类为\(a_{i,j}\) ,由于种类并不是很多,所以鲍勃决定让废土守望者来解决这些聒噪怪。

为了更为方便地解决这些聒噪怪,废土守望者提出了一个问题:有多少个正方形包含了恰好 \(k\) 种聒噪怪。鲍勃正忙于给某8位选手加油阴阳怪气,所以他没空回答问题,作为酒馆的常客,你有义务帮助鲍勃解决这个问题。

\(1\le n,m\le 1500;1\le k\le n\times m;1\le a_{i,j}\le 100.\)

讲解

我的做法是线段树套线段树+\(\tt bitset\),外面是类似尺取的做法,当然你也可以认为是 \(\tt two-pointer\),时间复杂度 \(O(\frac{100}{64}n^2\log^2_2n)\)。

题解的做法是二维 \(\tt st\) 表+二分,据它说是 \(O(n^2\log_2n)\)。

代码

卡过空间的代码
//12252024832524
#include <bitset>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 1501;
int n,m,k;
int a[MAXN][MAXN];
LL ans;

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

#define lc (x<<1)
#define rc (x<<1|1)
struct SegmentTree1
{
	bitset<100> t[4090];
	
	void up(int x){t[x] = t[lc] | t[rc];}
	
	void Build(int x,int l,int r,int ql,int qr)
	{
		if(l == r)
		{
			for(int i = ql;i <= qr;++ i) t[x][a[l][i]] = 1;
			return;
		}
		int mid = (l+r) >>1;
		Build(lc,l,mid,ql,qr); Build(rc,mid+1,r,ql,qr);
		up(x);
	}
	
	bitset<100> Query(int x,int l,int r,int ql,int qr)
	{
		if(ql <= l && r <= qr) return t[x];
		int mid = (l+r) >> 1; 
		if(ql <= mid) 
		{
			if(mid+1 <= qr) return Query(lc,l,mid,ql,qr) | Query(rc,mid+1,r,ql,qr);
			else return Query(lc,l,mid,ql,qr);
		}
		else return Query(rc,mid+1,r,ql,qr);
	}
}st[4090];
void Build(int x,int l,int r)
{
	st[x].Build(1,1,n,l,r);
	if(l == r) return;
	int mid = (l+r) >> 1;
	Build(lc,l,mid); Build(rc,mid+1,r);
}
int hang;
bitset<100> Query(int x,int l,int r,int ql,int qr)
{
	if(ql <= l && r <= qr) return st[x].Query(1,1,n,hang,hang+qr-ql);
	int mid = (l+r) >> 1; 
	if(ql <= mid) 
	{
		if(mid+1 <= qr) return Query(lc,l,mid,ql,qr) | Query(rc,mid+1,r,ql,qr);
		else return Query(lc,l,mid,ql,qr);
	}
	else return Query(rc,mid+1,r,ql,qr);
}

int main()
{
//	freopen("matrix.in","r",stdin);
//	freopen("matrix.out","w",stdout);
	n = Read(); m = Read(); k = Read();
	for(int i = 1;i <= n;++ i)
		for(int j = 1;j <= m;++ j)
			a[i][j] = Read()-1;
	Build(1,1,m);
	hang = 1;
	for(int i = 1;i <= n;++ i)
	{
		hang = i;
		int l = 0,r = 0,sx = n-i+1;
		for(int j = 1;j <= m;++ j)
		{
			while((r < j || Query(1,1,m,j,r+1).count() <= k) && r-j+1 < sx && r < m) ++ r;
			while((l < j-1 || Query(1,1,m,j,l+1).count() < k) && l-j+1 < sx && l < m) ++ l;
			ans += r-l; 
		}
	}
	Put(ans);
	return 0;
}

标签:le,int,酒馆,qr,Build,ql,聒噪
来源: https://www.cnblogs.com/PPLPPL/p/15385939.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有