题解 P1494 【[国家集训队]小Z的袜子】(基础莫队总结)

题目link
在某题解的基础上解释一下
fk和FK数组是分块优化
看完这篇咕咕日报 您就可以对基础莫队比较了解了
代码很简单,主要是gcd居然有函数(手动致远星++)


#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,col[50010],ans,L=1,R,s[50010],FK[50010];
struct node
{
	ll l;//左 
	ll r;//右 
	ll place;//原位置 
	ll numerator;//分子 
	ll denominator;//分母 
}Q[50010];//question
ll update(ll x,ll fh)
{
	ans-=s[col[x]]*s[col[x]];
	s[col[x]]+=fh;
	ans+=s[col[x]]*s[col[x]];
}
int cmp(node a,node b)
{
	if(FK[a.l]!=FK[b.l])
		return a.l<b.l;
	return a.r<b.r;
}
int Cmp(node a,node b)
{
	return a.place<b.place;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>col[i];
	}
	int fk=sqrt(n);
	for(int i=1;i<=m;i++)
	{
		cin>>Q[i].l>>Q[i].r;
		Q[i].place=i;
	}
	for(int i=1;i<=n;i++)
	{
		FK[i]=(i-1)/fk+1;
	}
	sort(Q+1,Q+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		for(;R<Q[i].r;R++)
		{
			update(R+1,1);
		}
        for(;R>Q[i].r;R--)
        {
        	update(R,-1);
        }
        for(;L<Q[i].l;L++)
        {
        	update(L,-1);
        }
        for(;L>Q[i].l;L--)
        {
        	update(L-1,1);
        }
        if(Q[i].l==Q[i].r)
        {
            Q[i].numerator=0;
            Q[i].denominator=1;
            continue;
        }
        Q[i].numerator=ans-(Q[i].r-Q[i].l+1);
        Q[i].denominator=(Q[i].r-Q[i].l+1)*(Q[i].r-Q[i].l);
        ll tmp=__gcd(Q[i].numerator,Q[i].denominator);
        Q[i].numerator/=tmp;
        Q[i].denominator/=tmp;
	}
	sort(Q+1,Q+m+1,Cmp);
	for(int i=1;i<=m;i++)
	{
		cout<<Q[i].numerator<<"/"<<Q[i].denominator<<endl;
	}
}

然后是可爱毒瘤的回滚莫队
更好的食用体验请点这里


#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,col[5000010],ans,L=1,R,s[5000010],FK[5000010],GG;
int fk;
struct node
{
    ll l;//左 
    ll r;//右 
    ll place;//原位置 
    ll ANS;
}Q[5000010];//question
int cmp(node a,node b)
{
    if(FK[a.l]!=FK[b.l])
        return a.l<b.l;
    return a.r<b.r;
}
int Cmp(node a,node b)
{
    return a.place<b.place;
}
int BaoLi(int x,int y)
{
    int res=-1;
    for(int i=x;i<=y;i++)
    {
        if(col[i]>res)
        {
            res=col[i];
        }
    }
    return res;
}
int md(int x,int y)
{
    L=min(x*fk,n)+1;
    R=L-1;
    ans=0;
    int RET=y; 
    for(int i=y;FK[Q[i].l]==x;i++)
    {
        if(FK[Q[i].l]==FK[Q[i].r])
        {
            Q[i].ANS=BaoLi(Q[i].l,Q[i].r);
        }
        for(;R<=Q[i].r;)
        {
            ans=max(ans,col[R]);
            R++;
        }
        int fy=ans;
        for(;L>=Q[i].l;)
        {
            ans=max(ans,col[L]);
            L--;    
        }
        Q[i].ANS=ans;
        L=min(x*fk,n)+1;
        ans=fy;
        RET++;
    }
    return RET;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&col[i]);
    }
    fk=sqrt(n);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&Q[i].l,&Q[i].r);
        Q[i].place=i;
    }
    for(int i=1;i<=n;i++)
    {
        FK[i]=(i-1)/fk+1;
    }
    sort(Q+1,Q+m+1,cmp);
    int now=1;
    for(int i=1;i<=FK[n];i++)
    {
        now=md(i,now);
    }
    sort(Q+1,Q+m+1,Cmp);
    for(int i=1;i<=m;i++)
    {
        printf("%d\n",Q[i].ANS);
    }
}
posted @ 2019-02-13 11:22  G_A_TS  阅读(500)  评论(0编辑  收藏  举报