歴史の研究回滚莫队板子题求调
查看原帖
歴史の研究回滚莫队板子题求调
231543
bloodstalk楼主2023/4/9 17:20

rt,从#36开始后面几乎就全错了,感觉没什么问题/kel 附记录

#include<bits/stdc++.h>
#define int long long
#define ll long long
#define next nxt
#define re register
#define il inline
const int N = 2e5 + 5;
const int M = 2e5 + 5;
const int SqrtN = 447 + 5;
using namespace std;
int max(ll x,ll y){return x > y ? x : y;}
int min(ll x,ll y){return x < y ? x : y;}

int n,m,s,sum;
ll Max,tempMax;//右边最值和用来拓展左区间的临时最值
struct node{
	int l,r,id;
}q[M];
int b[N],a[N],num[N],cnt[N],tempcnt[N];//b,a都是离散化用的,num求原数组第i位的数字,cnt是桶,tempcnt是临时桶
int st[SqrtN],ed[SqrtN],block[N];//分块相关
ll ans[M];

il int read()
{
	int f=0,s=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f |= (ch=='-');
	for(; isdigit(ch);ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
	return f ? -s : s;
}

il bool cmp(node a,node b)
{
	return (block[a.l] ^ block[b.l]) ? a.l < b.l : a.r < b.r;
}

il void init()
{
	s = sqrt(n);
	for(re int i=1;i<=n;i++)
	{
		st[i] = n / s * (i-1) + 1;
		ed[i] = n / s * i;
	}
	ed[s] = n;
	for(re int i=1;i<=s;i++)
		for(re int j=st[i];j<=ed[i];j++)
			block[j] = i;
}

il void brute_force(int x,int y,int id)
{
	tempMax = 0;//暴力
	for(re int i=x;i<=y;i++) tempcnt[a[i]]++;
	for(re int i=x;i<=y;i++) tempMax = max(tempMax,1ll*num[i]*tempcnt[a[i]]);
	ans[id] = tempMax;
	for(re int i=x;i<=y;i++) tempcnt[a[i]] = 0;
	return ;
}

il void Add(int x)
{
	++cnt[a[x]];
	Max = max(Max,cnt[a[x]]*num[x]);
}

signed main()
{
	n = read() , m = read();
	init();
	for(re int i=1;i<=n;i++) a[i] = b[i] = num[i] = read();
	sort(b+1,b+n+1);
	sum = unique(b+1,b+n+1) - b - 1;
	for(re int i=1;i<=n;i++) a[i] = lower_bound(b+1,b+sum+1,a[i]) - b;
	for(re int i=1;i<=m;i++) q[i] = {read(),read(),i};//离散化
	sort(q+1,q+m+1,cmp);
	int l = 1 , r = 0 , lastblock = 0;
	for(re int i=1;i<=m;i++)
	{
		if(block[q[i].l] == block[q[i].r]) { brute_force(q[i].l,q[i].r,q[i].id); continue; }
		if(block[q[i].l]+1 != lastblock)//判断是否要更改l的位置到下一个块上
		{
			Max = 0 , lastblock = block[q[i].l] + 1;
			memset(cnt , 0 , sizeof cnt);
			l = st[lastblock] , r = l - 1;
		}
		while(r < q[i].r) Add(++r);
		tempMax = Max;//伸长左区间
		for(re int j=q[i].l;j<l;j++)
		{
			tempcnt[a[j]]++;
			tempMax = max(tempMax,1ll*(tempcnt[a[j]]+cnt[a[j]])*num[j]);
		}
		for(re int j=q[i].l;j<l;j++) tempcnt[a[j]] = 0;
		ans[q[i].id] = tempMax;
	}
	for(re int i=1;i<=m;i++) cout << ans[i] << "\n";
	return 0;
}
2023/4/9 17:20
加载中...