您的位置:首页 > 其它

UVALive 5798 Jupiter Atacks!(线段树)

2015-09-23 14:57 351 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25634

题意:每组case给你B, P, L and N,代表常数B,取摸数P,数组长度L,N个操作。一开始数组【1-L】每个位置都为0,然后输入N个操作‘E' x y 代表把x位置的数改为y; 'H' x y 代表输出区间[ x , y ]按题目所给公式算出的值。

题解:线段树。有公式 f=B0f5 + B1f4 + B2f3 + B3f2 可以转换成 f=B3f2+B2f3+B1f4+B0f5 ,这样我们用线段树维护区间的 f 值,区间合并时假设fl代表左区间的f值,fr代表 右区间的 f 值,rnum 代表右区间的元素的个数

则 f = B ^ (rnum) *fl + fr; 查询时也同理

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#define lson id<<1,l,m
#define rson id<<1|1,m+1,r

using namespace std;

const int maxn=1e5+100;
typedef long long ll;

ll mod[maxn];
ll b,p;
int n,m;
ll sum[maxn*4];

void get_mod() {
    mod[0]=1;
    for(int i=1; i<=n; i++)
        mod[i]=(mod[i-1]*b)%p;
}

ll link_range(ll a,ll b,int k) {
    return (b+a*mod[k])%p;
}

void update(int id,int l,int r,int pos,int v) {
    if(l==r) {
        sum[id]=v;
        return ;
    }
    int m=(l+r)>>1;
    if(m>=pos)
        update(lson,pos,v);
    else
        update(rson,pos,v);
    sum[id]=link_range(sum[id<<1],sum[id<<1|1],r-m);
}

ll query(int id,int l,int r,int a,int b) {
    if(l>=a&&b>=r) {
        return sum[id];
    }
    int m=(l+r)>>1;
    ll rs,ls;
    rs=ls=0;
    if(a<=m)
        ls=query(lson,max(a,l),min(b,m));
    if(b>m)
        rs=query(rson,max(m+1,a),min(b,r));
    int rk=max(b-max(m+1,a)+1,0);
    return  link_range(ls,rs,rk);
}

int main() {
#ifdef ONLINE_JUDGE
#else
    freopen("in.txt","r",stdin);
#endif
    while(~scanf("%lld%lld%d%d",&b,&p,&n,&m)) {
        if(n==0)
            break;
        getchar();
        memset(sum,0,sizeof(sum));
        get_mod();
        for(int i=1; i<=m; i++) {
            char c;
            int x,y;
            scanf("%c %d %d",&c,&x,&y);
            getchar();
            if(c=='E')
                update(1,1,n,x,y);
            else
                printf("%lld\n",query(1,1,n,x,y));
        }
        puts("-");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: