【bzoj4320】ShangHai2006 Homework

*題目描述:
1:在人物集合 S 中加入一個新的程序員,其代號爲 X,保證 X 在當前集合中不存在。
2:在當前的人物集合中詢問程序員的mod Y 最小的值。 (爲什麼統計這個?因爲拯救
過世界的人太多了,只能取模)
*輸入:
第一行爲用空格隔開的一個個正整數 N。
接下來有 N 行,若該行第一個字符爲“A” ,則表示操作 1;若爲“B”,表示操作 2;
其中 對於 100%的數據:N≤100000, 1≤X,Y≤300000,保證第二行爲操作 1。
*輸出:
對於操作 2,每行輸出一個合法答案。
*樣例輸入:
5
A 3
A 5
B 6
A 9
B 4
*樣例輸出:
3
1
*提示:
【樣例說明】
在第三行的操作前,集合裏有 3、5 兩個代號,此時 mod 6 最小的值是 3 mod 6 = 3;
在第五行的操作前,集合裏有 3、5、9,此時 mod 4 最小的值是 5 mod 4 = 1;
*題解:
我們對於權值分塊,小於根號300000的直接記錄答案,大於的暴力枚舉倍數,維護兩個數組,記錄某個點的塊內的大於它的最小值,和每個塊的後面的最小的數,然後每次O(1)查就好了。
*代碼:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
    #define LL "%I64d"
#else
    #define LL "%lld"
#endif

#ifdef CT
    #define debug(...) printf(__VA_ARGS__)
    #define setfile() 
#else
    #define debug(...)
    #define filename ""
    #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
    R char ch; R int cnt = 0; R bool minus = 0;
    while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
    ch == '-' ? minus = 1 : cnt = ch - '0';
    while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
    return minus ? -cnt : cnt;
}
#define maxn 100010
#define maxs 610
#define maxss 300000
int ans[maxs], a[maxn];
int ans1[maxss + 10], ans2[maxs], id[maxss + 10], left[maxs], right[maxs];
int main()
{
//  setfile();
    memset(ans, 63, sizeof(ans));
    memset(ans1, 63, sizeof(ans1));
    memset(ans2, 63, sizeof(ans2));
    R int n = 0;
    R int block = sqrt(maxss);
    for (R int i = 1; i <= maxss; ++i) id[i] = i / block;
    for (R int i = 0; i <= maxss / block; ++i)
        left[i] = i * block, right[i] = (i + 1) * block - 1;
    for (R int q = FastIn(); q; --q)
    {
        R char opt = getc();
        while (opt < 'A' || opt > 'B') opt = getc();
        R int x = FastIn();
        if (opt == 'A')
        {
            a[++n] = x;
            for (R int i = 1; i < maxs; ++i) cmin(ans[i], x % i);
            for (R int i = left[id[x]]; i <= x; ++i) cmin(ans1[i], x);
            for (R int i = id[x] - 1; ~i; --i) cmin(ans2[i], x);
        }
        else
        {
            R int anss = maxss;
            if (x >= maxs)
                for (R int i = 0; i <= maxss; i += x)
                {
                    R int t = dmin(ans1[i], ans2[id[i]]);
                    cmin(anss, t - i);
                }
            else anss = ans[x];
            printf("%d\n", anss );
        }
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章