• bzoj4320: ShangHai2006 Homework


    神题 %%%tyb队长看到这题一眼分块,然后又不会仂。。。

    做法是这样的,对于Y<=block,直接暴力出解

    对于Y>=block 枚举每一个Y的每一个倍数,然后找到这个倍数在当前块的后继更新答案。

    但是有些时候,当前块没有Y的后继,那么就要去下一个块找,方便起见,mn[i]记录记录第i+1块~第block块最小值 

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int block=547;
    int st[310000];
    
    int bl[310000];//暴力把 Y<=block的答案硬算出来 
    int c[310000],mn[310000];//c[i]记录i同一个块的后继 mn[i]记录第i+1块~第block块最小值 
    void ins(int x)
    {
        for(int i=1;i<=block;i++)bl[i]=min(bl[i],x%i);
        for(int i=x;i>=0;i--)
        {
            if(st[i]!=st[i+1]&&i!=x)break;
            c[i]=min(c[i],x);
        }
        for(int i=st[x]-1;i>=1;i--)mn[i]=min(mn[i],x);
    }
    int query(int x)
    {
        if(x<=block)return bl[x];
        int ret=(1<<30);
        for(int i=0;i<=300000;i+=x)
            ret=min(ret,min(mn[st[i]],c[i])-i);
        return ret;
    }
    
    char ss[10];
    int main()
    {
        memset(bl,63,sizeof(bl));
        memset(mn,63,sizeof(mn));
        memset(c,63,sizeof(c));
        st[0]=1;for(int i=1;i<=300000;i++)st[i]=(i-1)/block+1;
        
        int n,x;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s%d",ss+1,&x);
            if(ss[1]=='A')ins(x);
            else printf("%d
    ",query(x));
        }
        return 0;
    }
  • 相关阅读:
    linux系统更新及开启自动更新
    关于ICO的一些理解
    中小学教育缴费遇到的一些问题
    中小学教育缴费----支付宝回传数据.net core 接收中文乱码
    中小学教育缴费——验签失败
    C# MVC+EF—WebApi
    C# MVC+EF—页面搭建
    C# MVC+EF—结构搭建
    EF中的预先加载和延迟加载
    WebApi路由
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8796852.html
Copyright © 2020-2023  润新知