[BZOJ4320] SHOI2006 Homework

Problem Description

1: adding a new character set S programmer, code-named X, ensure that X does not exist in the current collection.

2: the smallest value query programmer mod Y in the current set of characters. (Why this statistics? Because people had to save the world too much, only modulo)

Input Format

The first line of a space-separated positive integers N.

Then there are N rows, row if the first character is "A", it indicates an operation; if it is "B", 2 represents the operation;

Wherein for 100% data: N≤100000, 1≤X, Y≤300000, 1 ensure that the second operator behavior.

Output Format

For operation 2, each line of output a legitimate answer.

Sample input

5
A 3
A 5
B 6
A 9
B 4

Sample Output

3
1

link

BZOJ

Resolve

Maybe we can not let the algorithm do \ (O (nlogn) \) , but we can try \ (O (the n-\ sqrt {the n-}) \) !

Consider the root of the practice. From the title, the maximum modulus of no more than 300,000, then, may wish to set \ (GAP = \ sqrt 300000 \) , as a dividing line design algorithms.

For modulus less than (gap \) \ inquiry, we can directly open barrel recording the smallest answer. That came in each plus a number, from 1 to direct it \ (gap \) sweep again updated the answer. When asked to direct inquiries.

For modulus greater than \ (gap \) inquiry, set up the current inquiry modulus \ (mod \) , we wish to enumerate \ (mod \) multiples, for each query multiple of the current collection is larger than most of his close to his number, with the number of \ (mod \) remainder to update the answer. Consider disjoint-set to achieve. First 1-300000 all the numbers are in the same collection, adding a number \ (x \) , the set has been added to the last ratio (x \) \ small number \ (the y-\) , we \ (( y, x] \) in all numbers are merged into \ (x \) while the number of these into a single collection. direct queries to find his father. (If it is difficult to understand can look at the code)

The only problem is that we can not support the investigation and split sets. We can operate from back to front, so addend equivalent number of deleted, which is a collection of the merger.

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define N 500002
using namespace std;
const int inf=1<<30;
struct query{
    int op,x;
}q[N];
int n,i,j,fa[N],minx[N],ans[N];
int find(int x)
{
    if(x!=fa[x]) fa[x]=find(fa[x]);
    return fa[x]; 
}
int main()
{
    scanf("%d",&n);
    int gap=sqrt(300000);
    memset(minx,0x3f,sizeof(minx));
    memset(ans,-1,sizeof(ans));
    for(i=0;i<=300000;i++) fa[i]=i+1;
    fa[300001]=300001;
    for(i=1;i<=n;i++){
        char op;
        cin>>op;
        scanf("%d",&q[i].x);
        if(op=='A'){
            q[i].op=1;
            for(j=1;j<=gap;j++) minx[j]=min(minx[j],q[i].x%j);
            fa[q[i].x]=q[i].x;
        }
        else{
            q[i].op=2;
            if(q[i].x<=gap) ans[i]=minx[q[i].x];
        }
    }
    for(i=n;i>=1;i--){
        if(q[i].op==2&&q[i].x>gap){
            int tmp=inf;
            for(j=0;j<=300000;j+=q[i].x){
                int f=find(j);
                if(f<=300000) tmp=min(tmp,f%q[i].x);
            }
            ans[i]=tmp;
        }
        else if(q[i].op==1) fa[q[i].x]=q[i].x+1;
    }
    for(i=1;i<=n;i++){
        if(ans[i]!=-1) printf("%d\n",ans[i]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/12237101.html