xt 1149 线段树版的约瑟夫

来源:互联网 发布:损失函数优化 编辑:程序博客网 时间:2024/04/28 16:31

刺瞎了双眼啊,少了个LL,直接与一等奖失之交臂,二等里的第一,实在是一个悲伤的结局

归根结底,现场的状态弱爆了,这点放平常应该发现的


/**竟然WA在中间结果可能超32位上,害了我两天白费了*/#include <stdio.h>#define L(i) (i)<<1#define R(i) (i)<<1|1#define N 100001struct node{    int l,r,sum;}st[N<<2];void build(int l,int r,int id){    st[id].l = l;    st[id].r = r;    st[id].sum = r - l + 1;    if(l < r)    {        int mid = (l + r) / 2;        build(l,mid,L(id));        build(mid + 1,r,R(id));    }}int update(int p,int id){    st[id].sum --;    if(st[id].l == st[id].r)        return st[id].l;    return st[L(id)].sum >= p? update(p,L(id)) : update(p - st[L(id)].sum,R(id));}int main(){    int s,n,x,i,out[N],q[N],A,B,M,m;    while(scanf("%d%d%d%d%d%d",&n,&m,&x,&A,&B,&M) != EOF)    {        s = 1;        build(1,n,1);        int maxm = 0;        for(i = 0; i < m; ++i)        {            scanf("%d",&q[i]);            if(q[i] > maxm)                maxm = q[i];        }        for(i = 1; i <= maxm; ++i)        {            s = ( s + x - 1) % st[1].sum + 1;            out[i] = update(s, 1);            x = ( 1LL*x * A + B) % M ;        }        if(m)            printf("%d",out[q[0]]);        for(i = 1; i < m; ++i)            printf(" %d",out[q[i]]);        printf("\n");    }    return 0;}/**2 1 0 1 2 3141 5 1 1 0 21 2 3 4 403266 10 67800 73353 82726 838281 2 3 4 5 6 7 8 9 10*/



另附一神牛的线段树方案,吾等表示看不懂

#include <cstdio>#include <vector>#include <algorithm>using namespace std;const int MAXN = 1 << 17;struct SegTree {    int n, m;    int a[MAXN + MAXN];    static int L(int i) { return i << 1; }    static int R(int i) { return L(i) ^ 1; }    void init(int m) {        this->m = m;        n = 1;        while (n < m) {            n <<= 1;        }        fill(a + n, a + n + m, 1);        fill(a + n + m, a + n + n, 0);        for (int i = n - 1; i > 0; --i) {            a[i] = a[L(i)] + a[R(i)];        }    }    void reset(int i) {        i += n;        while (i > 0) {            --a[i];            i >>= 1;        }    }    int find(int p, int pl, int pr, int l, int r, int& k) {        if (pl == l && pr == r) {            if (a[p] <= k) {                k -= a[p];                return -1;            } else if (pr - pl == 1) {                return pl;            }        }        int pm = (pl + pr) / 2;        if (r <= pm) {            return find(L(p), pl, pm, l, r, k);        } else if (pm <= l) {            return find(R(p), pm, pr, l, r, k);        } else {            int ret = find(L(p), pl, pm, l, pm, k);            if (ret == -1) {                ret = find(R(p), pm, pr, pm, r, k);            }            return ret;        }    }    int find(int i, int k) {        k %= a[1];        i = find(1, 0, n, i, m, k);        if (i == -1) {            i = find(1, 0, n, 0, m, k);        }        return i;    }} st;int main() {    int n, q, x, a, b, m;    vector<pair<int, int> > v;    while (scanf("%d%d%d%d%d%d", &n, &q, &x, &a, &b, &m) != EOF) {      //  fprintf(stderr, "%d %d %d %d %d %d\n", n, q, x, a, b, m);        v.resize(q);        for (int i = 0; i < q; ++i) {            scanf("%d", &v[i].first);            v[i].second = i;        }        sort(v.begin(), v.end());        st.init(n);        for (int i = 0, j = 0, k = 0; i < q; ++i) {            while (j < v[i].first) {                ++j;                k = st.find(k, x);                st.reset(k);                x = (1LL * x * a + b) % m;            }            v[i].first = k;            swap(v[i].first, v[i].second);        }        sort(v.begin(), v.end());        for (int i = 0; i < q; ++i) {            if (i > 0) {                putchar(' ');            }            printf("%d", v[i].second + 1);        }        puts("");    }    return 0;}