莫队-----优美的暴力

最基础的莫队

例题:https://www.luogu.com.cn/problem/SP3267

先想想最菜的方法,显然,大家都会 \(O(nm)\)\(O(n^2)\) 的!

这个时候,

恭喜你!

获得了 \(0\)这是SPOJ

接着,你去想优化 (于是你就发现其实自己是会莫队的)

记录个cnt表示某个数有多少个,根据询问加加减减,如果左端点比询问小,则往右跑,并处理左端点的每个数,其它三种情况一样

这样,你发现复杂度有时候还是 \(O(nm)\) 的!

这个时候,你就去搜blog

发现!

有种高大上的暴力叫做莫队!!!

从此,你就爱上了莫队

100分与0分的差别,往往就是一个排序……

先把n分块,看l属于哪个块内

如果l所在的块不一样,则把l所在的块从小到大排序

否则,按r从小到大排序

这样就变成了 \(O(n\sqrt{n})\)

证明先咕着

吼了,康康这题代码吧

#include
using namespace std;
#define int long long
inline int read() {
	int x(0),neg(1);char ch(getchar());
	while(!isdigit(ch)) {
		if (ch=='-') neg=-1;
		ch=getchar();
	}
	while(isdigit(ch)) {
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*neg;
}
inline void print(int x)  {
    if(x/10) print(x/10);
    putchar(x%10+'0');
}
int n,q;
const int maxn=1000000;
int cnt[maxn+5];
struct node{
	int l,r,id;
}seg[maxn+5];
int num[maxn+5];
int tot;
int belong[maxn+5];
int ans[maxn+5];
inline bool cmp(const node &a,const node &b) {
	return belong[a.l]!=belong[b.l]?belong[a.l]seg[i].l) add(--l);
		while(rseg[i].r) del(r--);
		ans[seg[i].id]=tot;
	}
//	puts("ok");
	for (int i=1;i<=q;++i) {
		print(ans[i]);
		puts("");
	}
	return 0;
}

如果你还想优化!

你就得掌握一些专业的压行技巧了 /xyx

码风极差,勿喷~

带修莫队

显然,几个时间也就没了吧……

例题:https://www.luogu.com.cn/problem/P1903

写完后的我:

咦,这题怎么只有50pts?!

啊!原来块大小是这样的啊!

蛤?为啥改了还是60pts!

算了,开个O2吧……

于是,这是个开O2才能过的程序

#include
using namespace std;
//#define register int long long
namespace Fread{
	const int MAXN=1<<20;
	char buf[MAXN],*S,*T;
	inline char getchar() {
		if(S==T){
			T=(S=buf)+fread(buf,1,MAXN,stdin);
			if(S==T) return EOF;
		}
		return *S++;
	}
}
inline int read() {
	register int x(0),neg(1);char ch(getchar());
	while(!isdigit(ch)) {
		if (ch=='-') neg=-1;
		ch=getchar();
	}
	while(isdigit(ch)) {
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*neg;
}
#ifdef ONLINE_JUDGE
	#define getchar Fread::getchar
#endif
const int maxn=1000000;
int a[maxn+5],cnt[maxn+5],ans[maxn+5],bel[maxn+5];
struct node{
    int l,r,id,t;
}q[maxn+5];
struct update{
    int pos,color,last;
}h[maxn+5];
int cntq,cntu,n,m;
inline int cmp(const node &a,const node &b) {return (bel[a.l]^bel[b.l])?bel[a.l]q[i].l) qwq+=!cnt[a[--l]]++;
        while(rq[i].r) qwq-=!--cnt[a[r--]];
        while(timeq[i].t) {
            if(q[i].l<=h[time].pos && h[time].pos<=q[i].r) 
				qwq-=!--cnt[a[h[time].pos]]-!cnt[h[time].color]++;
            swap(a[h[time].pos],h[time].color);
            --time;
        }
        ans[q[i].id]=qwq;
    }
    for(register int i=1;i<=cntq;++i) 
        printf("%d\n",ans[i]);
    return 0;
}

你可能感兴趣的:(莫队-----优美的暴力)