最基础的莫队
例题: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;
}