BZOJ4320: 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

HINT

 

【样例说明】 

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

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

 

按权值分块,<=sqrt(300000)的答案直接爆算,>sqrt(300000)的答案可以枚举x/Y的整数部分。

那么问题就是如何快速计算>x的最小的数并带插入。

注意快速计算>x的最小的数并带删除可以用并查集来做,那么时光倒流一下就行了。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const int maxn=300010;
const int maxm=100010;
int pa[maxn],vis[maxn];
int A[maxm],type[maxm],res[410],ans[maxm];
inline int findset(int x) {return !pa[x]||x==pa[x]?x:pa[x]=findset(pa[x]);}
int main() {
    int SIZE=400;
    rep(i,1,SIZE) res[i]=1e9;
    int n=read();
    rep(i,1,n) {
        char s[2];int x;
        scanf("%s%d",s,&x);
        if(s[0]=='A') {
            type[i]=1;vis[x]=1;A[i]=x;
            rep(i,1,SIZE) res[i]=min(res[i],x%i);
        }
        else {
            if(x<=SIZE) ans[i]=res[x];
            else type[i]=2,A[i]=x;
        }
    }
    rep(i,1,300000) if(!vis[i]) pa[i]=i+1;
    dwn(i,n,1) if(type[i]) {
        if(type[i]==1) pa[A[i]]=A[i]+1;
        else {
            ans[i]=1e9;
            for(int j=0;j<=300000;j+=A[i]) {
                int x=findset(max(1,j));
                if(x<=300000) ans[i]=min(ans[i],x%A[i]);
            }
        }
    }
    rep(i,1,n) if(type[i]!=1) printf("%d\n",ans[i]);
    return 0;
}
View Code

 

posted @ 2015-11-22 20:52  wzj_is_a_juruo  阅读(262)  评论(0编辑  收藏  举报