codeforces1288E Messenger Simulator

https://codeforces.com/contest/1288/problem/E

莫队做的这题,根号常数慌得一匹,加了一堆常数优化,最后1081ms,怕被hack,最后主席树没冲出来,结果这题没被hack,A,D没了,艹,本来可以上波大分结果变成掉分。

下面的代码是没加优化前的,赛后测了一下是1949ms,差了将近一倍。。。。

很显然最前面要么是一开始的位置,要么是后面有message被调到第一位。

最后面那就是在调到第一位之后,在下次被调到第一位之前,有多少不同的数字。

可以在输入的数据前加上n n-1 n-2.....2 1,变成一个n+m的序列,方便处理。

区间不同的数字,强制在线的话可以用主席树,没到一个位置,就开一个rt把这个数字上次出现的位置删掉,再开一个rt把这个数字这次出现的位置+1,没强制在线的话可以直接莫队,我就莫队了(其实是忘记主席树可以写了,最后主席树WA9了没冲出来

看了牛逼网友的代码,由于这题可以从左到右或者从右到做按顺序求区间不同数字个数,所以树状数组也可以做,我太菜了.jpg,总是用复杂方法。。。

#include<bits/stdc++.h>
#define maxl 600010
 
using namespace std;
 
int n,m,ans,tot,sz,res;
int a[maxl],last[maxl],ansl[maxl],ansr[maxl],sum[maxl]; 
char s[maxl];
struct que
{
	int l,r,id;
}q[maxl];
 
inline void prework()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		ansl[i]=i,ansr[i]=i;
		last[i]=n+m+1,a[i]=n-i+1;
	}
	for(int i=n+1;i<=n+m;i++)
	{
		scanf("%d",&a[i]);
		ansl[a[i]]=1;
	}
	m=n+m;
	tot=0;
	for(int i=m;i>=1;i--)
	{
		if(i+1<=last[a[i]]-1)
			q[++tot]=que{i+1,last[a[i]]-1,a[i]};
		last[a[i]]=i;
	}
}
 
inline bool cmp(const que &a,const que &b)
{
	if(a.l/sz==b.l/sz)
		return (a.r<b.r);
	return a.l/sz<b.l/sz;
}
 
inline void add(int ind)
{
	if(sum[a[ind]]==0)
		res++;
	sum[a[ind]]++;
}
 
inline void del(int ind)
{
	if(sum[a[ind]]==1)
		res--;
	sum[a[ind]]--;
}
 
inline void mainwork()
{
	sz=sqrt(tot);
	sort(q+1,q+1+tot,cmp);
	int left=1,right=0;res=0;
	for(int i=1;i<=tot;i++)
	{
		while(right<q[i].r)		
			right++,add(right);
		while(right>q[i].r)
			del(right),right--;
		while(left<q[i].l)
			del(left),left++;
		while(left>q[i].l)
			left--,add(left);
		ansr[q[i].id]=max(ansr[q[i].id],res+1);
	}
}
 
inline void print()
{
	for(int i=1;i<=n;i++)
		printf("%d %d\n",ansl[i],ansr[i]);
}
 
int main()
{
	int t=1;
	//scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值