zoukankan      html  css  js  c++  java
  • 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】

    ShangHai2006 Homework

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 918  Solved: 460
    [Submit][Status][Discuss]

    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

    HINT

    【样例说明】 

      在第三行的操作前,集合里有 3、5 两个代号,此时 mod 6 最小的值是 3 mod 6 = 3; 

      在第五行的操作前,集合里有 3、5、9,此时 mod 4 最小的值是 5 mod 4 = 1; 

    1.插入一个数X 
    2.询问所有数 mod Y的最小值

    将询问按照Y3105−−−−−√Y>3105−−−−−√两种分类

    Y3105−−−−−√:开一个数组ansY代表当询问为Y的时候的答案,每插入一个数枚举1i3105−−−−−√X mod i更新ansi

    Y>3105−−−−−√:枚举Y的倍数kY,对于每个kY我们需要找到集合中大于等于kY的数中最小的那个 
    log系列显然会T 
    考虑并查集,类似于花神游历各国那个题一样,我们可以利用并查集完成【删除一个数,迅速找到一个位置后面第一个没有被删除的数】 
    但是这个题是插入一个数啊? 
    倒着做就行了

     1 #include<cstring>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstdio>
     6 
     7 #define T 300007
     8 #define B 507
     9 #define M 300007
    10 #define ll long long
    11 using namespace std;
    12 inline int read()
    13 {
    14     int x=0,f=1;char ch=getchar();
    15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
    16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    17     return x*f;
    18 }
    19 
    20 int n;
    21 int fa[M],opt[M],num[M];
    22 int mn[M],ans[M];
    23 
    24 int find(int x)
    25 {
    26     return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
    27 }
    28 int main()
    29 {
    30     scanf("%d",&n);
    31     memset(mn,127,sizeof(mn));
    32     for(int i=1;i<=T;i++)fa[i]=i+1;
    33     for(int i=1;i<=n;i++)
    34     {
    35         char s[5]; 
    36         scanf("%s%d",s,&num[i]);
    37         opt[i]=s[0]-'A';
    38         if(opt[i]==0)
    39         {
    40             for(int j=1;j<=B;j++)
    41                 mn[j]=min(mn[j],num[i]%j);
    42             fa[num[i]]=num[i];
    43         }
    44         else if(num[i]<=B) ans[i]=mn[num[i]];
    45     }
    46     for(int i=n;i;i--)
    47     {
    48         if(opt[i]==0)
    49             fa[num[i]]=fa[num[i]+1];
    50         else if(num[i]>B)
    51         {
    52             ans[i]=find(1)%num[i];
    53             for(int j=num[i];j<=T;j+=num[i])
    54             {
    55                 int x=find(fa[j]);
    56                 if(x)ans[i]=min(ans[i],x%num[i]);
    57             }
    58         }
    59     }
    60     for(int i=1;i<=n;i++)
    61         if(opt[i]==1)
    62             printf("%d
    ",ans[i]);
    63 }
  • 相关阅读:
    图片处理
    define 常量的定义和读取
    curl
    stream_get_contents 和file_get_content的区别
    php flock 文件锁
    字符串函数
    php 常量
    debug_backtrace()
    pathlib模块替代os.path
    Python中对 文件 的各种骚操作
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8168755.html
Copyright © 2011-2022 走看看