bzoj 4320: ShangHai2006 Homework分块

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4320: ShangHai2006 Homework分块相关的知识,希望对你有一定的参考价值。

按根号300000=m分情况讨论
查询是,当x小于等于m,那么可以暴力记录直接出解;否则,用分块维护区间值,查询的时候以x为步长跳根号m次取最小值即可
还有一种并查集方法,来自https://www.cnblogs.com/CQzhangyu/p/7088337.html
技术分享图片

#include<iostream>
#include<cstdio>
using namespace std;
const int N=300010,M=550;
int n=300000,m=n/M,q,i,x,bl[N],s[M],f[N],tg[M],g[M];
char op[5];
int main()
{
    for(int i=1;i<=n;i++)
        bl[i]=i/M;
    for(int i=n;i;i--)
        s[bl[i]]=i;
    for(int i=1;i<=n;i++)
        f[i]=N;
    for(int i=0;i<=m;i++)
        tg[i]=N;
    for(int i=1;i<M;i++)
        g[i]=N;
    scanf("%d",&q);
    while(q--)
    {
        scanf("%s%d",op,&x);
        if(op[0]==‘A‘)
        {
            for(int i=1;i<M;i++)
                g[i]=min(g[i],x%i);
            for(int i=s[bl[x]];i<=x;i++)
                f[i]=min(f[i],x);
            for(int i=bl[x]-1;i>=0;i--)
                tg[i]=min(tg[i],x);
        }
        else 
        {
            if(x<M)
                printf("%d
",g[x]);
            else
            {
                int t=N;
                for(int i=0,j=x;i<=n;i=j,j+=x)
                {
                    if(j>n)
                        j=n+1;
                    int y=min(f[max(1,i)],tg[bl[max(1,i)]]);
                    if(y<j)
                        t=min(t,y-i);
                }
                printf("%d
",t);
            }
        }
    }
    return 0;
}



以上是关于bzoj 4320: ShangHai2006 Homework分块的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4320 ShangHai2006 Homework

4320: ShangHai2006 Homework

BZOJ 4320 Homework

BZOJ1001: [BeiJing2006]狼抓兔子

bzoj1003 [ZJOI2006]物流运输

bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)