莫队这东西其实就是一种优化了的暴力,具体原理很好理解,不用我吹,复杂度证明也不用我吹。
如题是一道水题,其实是莫队经典题,莫队就是出自这道题的。这道题是当年莫涛队长出的一道题,是第一道莫队题。
如果你会莫队就一定会,代码如下:
#include"cstdio"
#include"cmath"
#include"algorithm"
#include"cstring"
#include"iostream"
#define LL long long
#define Rep(i,n,x) for(i=x;i<=n;i++)
using namespace std;
struct mes
{
LL l,r,ans1,ans2,dir;
};
mes c[50001];
LL a[50001],b[50001];
int k;
inline LL read()
{
char c=getchar();int x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
bool cmp1(mes x,mes y)
{
return ((x.l/kc[i].l){
l--;
ans+=a[b[l]];
a[b[l]]++;
}
while(rc[i].r){
a[b[r]]--;
ans-=a[b[r]];
r--;
}
c[i].ans1=ans;
c[i].ans2=(r-l+1)*(r-l)/2;
gcd(c[i].ans1,c[i].ans2);
}
sort(c+1,c+m+1,cmp2);
Rep(i,m,1)
printf("%lld/%lld\n",c[i].ans1,c[i].ans2);
return 0;
}
第一次打莫队码风似乎有点骚。还有由于BZOJ很爆炸所以为了大家浏览方便些接了洛谷的链接。
代码如下:
#include"cstdio"
#include"algorithm"
#include"iostream"
#include"cmath"
#include"cstring"
#define LL long long
#define MAXN 50000+10
#define Rep(i,n,x) for(i=x;i<=n;i++)
using namespace std;
inline LL read()
{
char c=getchar();LL x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
struct asks
{
LL l,r,NO,ans;
};
asks a[MAXN];
LL num[MAXN],cnt[MAXN],n,m,k,p;
bool cmp1(asks x,asks y)
{
return ((x.l/pa[i].l)
{
l--;
ans+=cnt[num[l]]*2+1;
cnt[num[l]]++;
}
while(ra[i].r)
{
ans-=cnt[num[r]]*2-1;
cnt[num[r]]--;
r--;
}
a[i].ans=ans;
}
sort(a+1,a+m+1,cmp2);
Rep(i,m,1)
printf("%lld\n",a[i].ans);
return 0;
}
#include"cstdio"
#include"algorithm"
#include"cmath"
#include"iostream"
#define Rep(i,n,x) for(i=x;i<=n;i++)
#define MAXN 10000+10
using namespace std;
struct asks
{
int l,r,time,ans,dir;
};
asks a[MAXN];
int num[MAXN],anses[MAXN],n,m,p;
int color[1000001];
struct change
{
int place,next;
};
change b[1002];
inline int read()
{
char c=getchar();int x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
bool cmp(asks x,asks y)
{
return ((x.l/p=l&&b[now].place<=r)
{
color[num[b[now].place]]--;
if(color[num[b[now].place]]==0)
ans--;
color[b[now].next]++;
if(color[b[now].next]==1)
ans++;
}
swap(num[b[now].place],b[now].next);
}
int main()
{
n=read(),m=read();
int i,j;
Rep(i,n,1)
num[i]=read();
int v=1,k=0;
Rep(i,m,1)
{
char p1=getchar();
while(p1!='Q'&&p1!='R')p1=getchar();
if(p1=='Q')
{
a[++k].l=read();
a[k].r=read();
a[k].time=v;
a[k].dir=k;
}
else
{
v++;
b[v].place=read();
b[v].next=read();
}
}
p=sqrt(n);
sort(a+1,a+k+1,cmp);
int l=1,r=0,t=1,ans=0;
Rep(i,k,1)
{
while(a[i].la[i].r){color[num[r]]--;if(color[num[r]]==0)ans--;r--;}
while(ta[i].time){turn(t,l,r,ans);t--;}
anses[a[i].dir]=ans;
}
Rep(i,k,1)
printf("%d\n",anses[i]);
return 0;
}
#include"cstdio"
#include"cmath"
#include"algorithm"
#define MAXN 1000001
#define Rep(i,n,x) for(i=x;i<=n;i++)
using namespace std;
struct ask
{
int l,r,dis;
};
inline int read()
{
char c=getchar();int x=0;
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
ask asks[200001];
int color[MAXN];
int num[50001],anses[200001],p;
bool cmp(ask x,ask y)
{
return ((x.l/pasks[i].l){l--;color[num[l]]++;if(color[num[l]]==1)ans++;}
while(rasks[i].r){color[num[r]]--;if(color[num[r]]==0)ans--;r--;}
anses[asks[i].dis]=ans;
}
Rep(i,m,1)
printf("%d\n",anses[i]);
return 0;
}