其他分享
首页 > 其他分享> > 题解-[SDOI/SXOI2022]整数序列

题解-[SDOI/SXOI2022]整数序列

作者:互联网

数据范围很诈骗,但poly log做法思考无果还是指引我们来想sqrt做法。

首先有一个很暴力的 \(O(cnt_x+cnt_y)\) 的做法。看到和出现次数有关则可以想根号分治。我们设定一个阈值 \(B\),对于两者都 \(<B\) 的部分可以暴力做,都大于 \(B\) 的部分也可以暴力做,因为这样的最多只会有 \(N^2/B\) 次计算。

然后思考一大一小,容易发现两者顺序无关,不妨设 \(cnt_x>cnt_y\)。

那么容易想到 \(x\) 中有很多是不必要的部分。实际上只有 \(y\) 中每个极长元素段在 \(x\) 中的相同长度的前驱和后继才是必要的。然而还有一个问题就是这样不合法的情况有可能变合法,那么我们不妨再放入一段前驱的前驱段。这样就把 \(x\) 的长度变得和 \(y\) 同阶了。

总的预处理复杂度变为 \(O(\frac{n^2}{B})\),总复杂度 \(O(\frac{n^2}{B}+qB)\),取 \(B=\frac{n}{\sqrt{q}}\) 即可得到 \(O(n\sqrt{q})\)。

实现细节可以考虑离线询问,然后预处理前驱后继,全部归并排序后再去重。

#include<bits/stdc++.h>
#define pb push_back
#define pii pair<int,int>
#define MP make_pair
#define F first
#define S second
using namespace std;
typedef long long ll;
const int maxn=2e6+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
template<typename T>
void read(T &x){
	T sgn=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar())if(ch=='-')sgn=-1;
	for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	x*=sgn;
}
int n,m,a[maxn],b[maxn],num;
int B,pre[maxn],nxt[maxn],len;
int d[maxn],e[maxn],f[maxn],g[maxn];
vector<int>vec[maxn];
vector<pii>qry[maxn];
ll s1[maxn],s2[maxn],mp[maxn];
pii c[maxn];
bool vis[maxn],mark[maxn],zz[maxn];
map<pii,ll> ans;
ll Ans[maxn];
ll BF(){
	ll now=-inf;
	vis[n]=1;mp[n]=0;
	for(int k=1;k<=len;k++){
		s1[k]=s1[k-1]+b[c[k].S];
		s2[k]=s2[k-1]+c[k].F;
		if(vis[s2[k]+n])now=max(now,s1[k]-mp[s2[k]+n]);
		if(!vis[s2[k]+n])mp[s2[k]+n]=s1[k],vis[s2[k]+n]=1;
		else mp[s2[k]+n]=min(mp[s2[k]+n],s1[k]);
	}
	vis[n]=0;
	for(int k=1;k<=len;k++)vis[s2[k]+n]=0;
	return now;
}
int main(){
//	freopen("sequence.in","r",stdin);
//	freopen("sequence.out","w",stdout);
	read(n);read(m);
	for(int i=1;i<=n;i++)read(a[i]),vec[a[i]].pb(i);
	for(int i=1;i<=n;i++)if(vec[i].size())num++;
	for(int i=1;i<=n;i++)read(b[i]);
	B=n/sqrt(m)+1;
	for(int i=1;i<=m;i++){
		int x,y;
		read(x);read(y);
		if(ans.find(MP(x,y))!=ans.end()){Ans[i]=ans[MP(x,y)];continue;};
		if(((int)vec[x].size()<B&&(int)vec[y].size()<B)||((int)vec[x].size()>=B&&(int)vec[y].size()>=B)){
			len=0;
			for(int p=0,q=0;p<(int)vec[x].size()||q<(int)vec[y].size();){
				if(p>=(int)vec[x].size())c[++len]=MP(-1,vec[y][q++]);
				else if(q>=(int)vec[y].size())c[++len]=MP(1,vec[x][p++]);
				else{
					if(vec[x][p]<vec[y][q])c[++len]=MP(1,vec[x][p++]);
					else c[++len]=MP(-1,vec[y][q++]);
				}
			}
			Ans[i]=ans[MP(x,y)]=ans[MP(y,x)]=BF();
		}else{
			if(vec[x].size()<vec[y].size())swap(x,y);
			qry[x].pb(MP(y,i));
		}
	}
	for(int i=1;i<=n;i++)if(qry[i].size()){
		for(int j:vec[i])mark[j]=1;
		for(int j=1;j<=n;j++){
			pre[j]=pre[j-1];
			if(mark[j-1])pre[j]=j-1;
		}
		nxt[n+1]=n+1;
		for(int j=n;j;j--){
			nxt[j]=nxt[j+1];
			if(mark[j+1])nxt[j]=j+1;
		}
		for(pii o:qry[i]){
			int j=o.F;
			if(ans.find(MP(i,j))!=ans.end()){
				Ans[o.S]=ans[MP(i,j)];
				continue;
			}
			len=0;
			int u=0,v=0,w=0,tmp=0;
			for(int k:vec[j]){
				if(nxt[k]<=n){
					if(nxt[k]>tmp)d[++u]=tmp=nxt[k];
					else if(nxt[tmp]<=n)d[++u]=tmp=nxt[tmp];
				}
			}
			tmp=n+1;
			for(int l=(int)vec[j].size()-1;~l;l--){
				int k=vec[j][l];
				if(pre[k]){
					if(pre[k]<tmp)e[++v]=tmp=pre[k];
					else if(pre[tmp])e[++v]=tmp=pre[tmp];
					if(pre[tmp])e[++v]=tmp=pre[tmp];
				}
			}
			reverse(e+1,e+1+v);
			for(int p=1,q=1;p<=u||q<=v;){
				if(p>u)f[++w]=e[q++];
				else if(q>v)f[++w]=d[p++];
				else{
					if(d[p]<e[q])f[++w]=d[p++];
					else f[++w]=e[q++];
				}
			}
			for(int p=1,q=0;p<=w||q<(int)vec[j].size();){
				if(p>w)g[++len]=vec[j][q++];
				else if(q>=(int)vec[j].size())g[++len]=f[p++];
				else{
					if(f[p]<vec[j][q])g[++len]=f[p++];
					else g[++len]=vec[j][q++];
				}
			}
			tmp=len;len=0;
			for(int k=1;k<=tmp;k++){
				if(g[k]!=g[len])g[++len]=g[k];
			}
			for(int k=1;k<=len;k++){
				c[k].F=a[g[k]]==i?1:-1;
				c[k].S=g[k];
			}
			Ans[o.S]=ans[MP(i,j)]=ans[MP(j,i)]=BF();
			for(int k=1;k<=len;k++)if(a[c[k].S]==i)zz[c[k].S]=0;
		}
		for(int j:vec[i])mark[j]=0;
	}
	for(int i=1;i<=m;i++)printf("%lld\n",Ans[i]);
	return 0;
}

标签:ch,SDOI,SXOI2022,++,题解,else,int,maxn,vec
来源: https://www.cnblogs.com/zcr-blog/p/16329118.html