zoukankan      html  css  js  c++  java
  • BZOJ_4320_ShangHai2006 Homework_分块

    BZOJ_4320_ShangHai2006 Homework_分块

    Description

      1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在。 
      2:在当前的人物集合中询问程序员的mod Y 最小的值。 (为什么统计这个?因为拯救
    过世界的人太多了,只能取模) 

    Input

    第一行为用空格隔开的一个个正整数 N。 
    接下来有 N 行,若该行第一个字符为“A” ,则表示操作 1;若为“B”,表示操作 2; 
    其中 对于 100%的数据:N≤100000, 1≤X,Y≤300000,保证第二行为操作 1。 

    Output

    对于操作 2,每行输出一个合法答案。 

    Sample Input

    5
    A 3
    A 5
    B 6
    A 9
    B 4

    Sample Output

    3
    1


    这种求的东西很奇怪的题要想到根号分治。

    考虑小于$sqrt y$这部分答案每次可以暴力更新,设g[i]为当y为i时的答案。

    大于$sqrt y$的这部分相当于有若干后缀,在每个后缀里找最小值,一共最多不超过$sqrt y$个后缀,那么我们可以$O(sqrt y)$修改$O(1)$查每个后缀。

    具体地,更新时用x更新这个块左端点到x的信息和前面那些块的信息。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    using namespace std;
    #define N 3000050
    #define RR register
    int M=550;
    int pos[N],L[N],f[N],g[N],tag[N],n=3000000;
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        RR int x=0; RR char c=nc();
        while(c<'0'||c>'9') c=nc();
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=nc();
        return x;
    }
    inline char rc() {
        RR char c=nc();
        while(c!='A'&&c!='B') c=nc();
        return c;
    }
    char pbuf[10000000] , *pp = pbuf;
    inline void write(int x) {
        static int sta[35];
        RR int top = 0;
        if(!x)sta[++top]=0;
        while(x) sta[++top] = x % 10 , x /= 10;
        while(top) *pp ++ = sta[top -- ] ^ '0';
    }
    void add(int x) {
        int i;
        for(i=1;i<=M;i++) {
            g[i]=min(g[i],x%i);
        }
        for(i=L[pos[x]];i<=x;i++) f[i]=min(f[i],x);
        for(i=pos[x]-1;i>=0;i--) tag[i]=min(tag[i],x);
    }
    int ask(int x) {
        if(!x) x++;
        return min(tag[pos[x]],f[x]);
    }
    int solve(int x) {
        if(x<M) return g[x];
        int t=N,i,j;
        for(i=0,j=x;i<=n;i=j,j+=x) {
            if(j>n) j=n+1;
            int y=ask(i);
            if(y<j) t=min(t,y-i);
        }
        return t;
    }
    int main() {
        int i;
        for(i=1;i<=n;i++) pos[i]=i/M,f[i]=N;
        for(i=n;i;i--) L[pos[i]]=i;
        for(i=1;i<M;i++) g[i]=N;
        for(i=0;i<=n/M;i++) tag[i]=N;
        int q; q=rd();
        int x;
        while(q--) {
            char opt=rc(); x=rd();
            if(opt=='A') {
                add(x); 
            }else {
                write(solve(x)); *pp++='
    ';
            }
        }
        fwrite(pbuf,1,pp-pbuf,stdout);
    }
    
  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/suika/p/9062515.html
Copyright © 2011-2022 走看看