莫队的各种杂题,博主真不要脸分明是水题

莫队这东西其实就是一种优化了的暴力,具体原理很好理解,不用我吹,复杂度证明也不用我吹。

NO.1:小Z的袜子

如题是一道水题,其实是莫队经典题,莫队就是出自这道题的。这道题是当年莫涛队长出的一道题,是第一道莫队题。

如果你会莫队就一定会,代码如下:

#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很爆炸所以为了大家浏览方便些接了洛谷的链接。

NO.2:小B的询问

比小Z的袜子水,就更不用解说了。

代码如下:

#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;
} 

NO.3:数颜色

一道待修改的莫队,其实就是比普通莫队多加一维,这道题难度比上道高些。
#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;
} 

NO.4:SDOI2009 HH的项链

naive,还可以用主席树来做,虽然很想用主席树来做但我还是忍住了(大雾)。
代码如下:
#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;
}


你可能感兴趣的:(暴力算法)