2014.7.29 - 多校3

来源:互联网 发布:韦东山 java 编辑:程序博客网 时间:2024/05/05 05:35

http://blog.sina.com.cn/s/blog_6bddecdc0102uyp3.html


hdu-4889-Scary Path Finding Algorithm

problem

think

构造。按照题解的构造方法写了一个。想不出来啊。

code

int bit[100];long long spfa_slf(int C, int nn) {    int n,m;    n = nn*2+1;    m = n*3;    vector<pair<int,int> > edges[111];    for(int i = 1; i <= nn; ++i){    //cout<<i<<"   "<<C<<"   "<<nn<<endl;        int id1 = 2*i - 1;        int id2 = 2*i;        int id3 = 2*i+1;        int x, y, w;        x = id1;        y = id2;        w = 0;        //cout<<x<<"  "<<y<<"  "<<w<<endl;        edges[x].push_back(make_pair(y,-w));        x = id1;        y = id3;        w = bit[nn-i];        //cout<<x<<"  "<<y<<"  "<<w<<endl;        edges[x].push_back(make_pair(y,-w));        x = id2;        y = id3;        w = bit[nn-i+1];        //cout<<x<<"  "<<y<<"  "<<w<<endl;        edges[x].push_back(make_pair(y,-w));    }    deque<int> q;    vector<long long> dist(n+1, ~0ULL>>1);    vector<bool> inQueue(n+1, false);    dist[1] = 0;    q.push_back(1);    inQueue[1] = true;    int doge = 0;    while(!q.empty()) {        int x = q.front(); q.pop_front();        //cout<<x<<endl;        //cout<<"+++++++  "<<q.size()<<"    "<<doge<<"  "<<C<<endl;        if(doge++ > C) {            puts("doge");            //cout<<endl<<"          "<<C<<endl;            return 233;        }        for(vector<pair<int,int> >::iterator it = edges[x].begin();        it != edges[x].end();++it) {            int y = it->first;            int w = it->second;            if(dist[y] > dist[x] + w) {                dist[y] = dist[x] + w;                if(!inQueue[y]) {                    inQueue[y] = true;                    if(!q.empty() && dist[y] > dist[q.front()])                        q.push_back(y);                    else                        q.push_front(y);                }            }        }        inQueue[x] = false;    }    return dist[n];}int main(){    int C;    bit[0] = 1;    for(int i = 1; i <= 31; ++i) bit[i] = bit[i-1] * 2;    bit[0] = 0;    while(scanf("%d", &C) != EOF){        if(C < 0){            puts("2 1");            puts("1 2 1");            continue;        }        ++C;        int n = 1;        int N = 2;        while(N < C){            ++n;            N *= 2;        }        printf("%d %d\n", 2*n+1, 3*n);        for(int i = 1; i <= n; ++i){            int id1 = 2*i - 1;            int id2 = 2*i;            int id3 = 2*i+1;            printf("%d %d %d\n", id1, id2, 0);            printf("%d %d %d\n", id1, id3, -bit[n-i]);            printf("%d %d %d\n", id2, id3, -bit[n-i+1]);        }        //spfa_slf(C, n);    }    return 0;}


hdu-4893-Wow! Such Sequence!

problem

n个点,m个操作。

1 x y,第x个数加y

2 x y,第x个数到第y个数的和

3 x y,第x个数到第y个数分别变成和他差的绝对值最小的那个fib数,如果前后两个一样变成前一个。

think

线段树。存两个值,一个是实际值,一个是fib值。

code

const int N = 111111;ll fb[10000];ll t[N<<2][2];int L[N<<2], R[N<<2];int op[N<<2];//0 1 2int n, m;void gao() {    fb[0] = 1, fb[1] = 1;    for (int i = 2; i <= 91; i++) fb[i] = fb[i - 1] + fb[i - 2];//, cout<<fb[i]<<endl;}void build(int l, int r, int k){    L[k] = l;    R[k] = r;    op[k] = 0;    t[k][0] = 0;    t[k][1] = r - l + 1;    if(l == r) return;    int mid = ( l + r) >> 1;    build(l, mid, k<<1);    build(mid+1, r, k<<1|1);}void down(int k){    if(op[k] == 1){        op[k<<1] = 1;        t[k<<1][0] = t[k<<1][1];        op[k<<1|1] = 1;        t[k<<1|1][0] = t[k<<1|1][1];    }    op[k] = 0;}void up(int k){    op[k] = 0;    for(int i = 0; i <= 1; ++i) t[k][i] = t[k<<1][i] + t[k<<1|1][i];}void update1(int a, int k, ll d){    if(a== L[k] && a == R[k]){        ll tmp = t[k][0] + d;        t[k][0] = tmp;        int fuck = lower_bound(fb, fb + 92, tmp) - fb;        if (fb[fuck] == tmp) t[k][1] = fb[fuck];        else if (fuck == 0) t[k][1] = 1;        else {            if (tmp - fb[fuck - 1] > fb[fuck] - tmp) t[k][1] = fb[fuck];            else t[k][1] = fb[fuck - 1];        }        op[k] = 0;        return ;    }    down(k);    int mid = (L[k] + R[k]) >> 1;    if(a<=mid) update1(a, k<<1, d);    else update1(a, k<<1|1, d);    up(k);}void update2(int l, int r, int k){    if(l == L[k] && r == R[k]){        op[k] = 1;        t[k][0] = t[k][1];        return ;    }    down(k);    int mid = (L[k] + R[k]) >> 1;    if(r <= mid) update2(l, r, k<<1);    else if(l > mid) update2(l, r, k<<1|1);    else{        update2(l, mid, k<<1);        update2(mid+1, r, k<<1|1);    }    up(k);}ll query(int l, int r, int k){    if(l == L[k] && r == R[k]) return t[k][0];    down(k);    int mid = (L[k] + R[k]) >> 1;    if(r <= mid) return query(l, r, k<<1);    else if(l > mid) return query(l, r, k<<1|1);    else return (query(l, mid, k<<1) + query(mid+1, r, k<<1|1));}int main () {    gao();    while(scanf("%d%d", &n, &m) != EOF){        build(1, n, 1);        for(int i = 0; i < m; ++i){            int oo, l, r;            ll d;            scanf("%d%d", &oo, &l);            if(oo == 1){                scanf("%I64d", &d);                update1(l, 1, d);            } else if(oo == 2){                scanf("%d", &r);                printf("%I64d\n", query(l, r, 1));            } else {                scanf("%d", &r);                update2(l, r, 1);            }        }    }    return 0;}


0 0
原创粉丝点击