• UVALive


    Jupiter Atacks!

    /**
        题意:B,P,L,N,分别表示进制,mod,数组的个数,操作数
        做法:树状数组  欧几里得  每个数加入到数组Tree的数是 B^(L-i)
        用树状数组进行维护前缀和,然后求一段区间的数,除以B^(L-j)
        因为(前缀和/B^(L-j)) 很大不好计算,所以就用乘法逆元 
           (k是a关于p的乘法的逆元) a*k≡1 (mod p) === (a/b)mod p (b关于p的乘法的逆元)
        PS(当我们要求(a/b) mod p的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
            我们可以通过求b关于p的乘法逆元k,将a乘上k再模p,即(a*k) mod p。其结果与(a/b) mod p等价。)
    **/
    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <cmath>
    #include <stdio.h>
    #define maxn 200000 + 10
    using namespace std;
    long long Tree[maxn];
    long long mmap[maxn];   ///逆元
    long long _next[maxn];  /// 次方
    long long extend_gcd(long long a,long long b,long long &x,long long &y)
    {
        if(a == 0 && b == 0) return -1;
        if(b == 0)
        {
            x = 1;
            y = 0;
            return a;
        }
        long long d = extend_gcd(b,a%b,y,x);
        y -= a/b*x;
        return d;
    }
    long long mod_reverse(long long a,long long n)
    {
        long long x,y;
        long long d = extend_gcd(a,n,x,y);
        if(d == 1) return (x%n+n)%n;
        else return -1;
    }
    long long B,P,L,N;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x, long long value)
    {
        for(int i = x; i <= L; i += lowbit(i))
        {
            Tree[i] = ((Tree[i] + value) % P + P) % P;
        }
    }
    long long getsum(int x)
    {
        long long sum =0;
        for(int i=x; i; i -= lowbit(i))
            sum = ((sum + Tree[i])%P + P)%P;
        return sum;
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%lld %lld %lld %lld",&B,&P,&L,&N))
        {
            if(B == 0 && P == 0 && L == 0 &&N == 0) break;
            memset(Tree,0,sizeof(Tree));
            memset(mmap,0,sizeof(mmap));
            memset(_next,0,sizeof(_next));
            int tmp = 1;
            mmap[L] = 1;
            _next[L] = 1;
            for(int i=L-1; i>=1; i--)
            {
                tmp = (tmp *B) %P;
                mmap[i] = mod_reverse(tmp,P);
                _next[i] = tmp;
            }
    
            int u,v;
            char ch[10];
            for(int i=1; i<=N; i++)
            {
                scanf("%s %d %d",ch,&u,&v);
                //cout<<ch<<" "<<u<<" "<<v<<endl;
                if(ch[0] == 'E')
                {
                    long long ans = (getsum(u) - getsum(u-1));
                    ans -= v*_next[u];
                    add(u,-ans);
                }
                else if(ch[0] == 'H')
                {
                    long long ans = ((getsum(v) - getsum(u-1))%P +P)%P;
                    //cout<<"ans = "<<ans<<endl;
                    ans = (ans *mmap[v])%P;
                    printf("%lld
    ",ans);
                }
            }
            printf("-
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    C语言计时
    time模块
    大端对齐 和小端对齐
    python之生成器与迭代器
    python之字符串反转
    简单排序
    Python学习笔记——切片
    Python学习笔记——函数(二)
    Python学习笔记——函数(一)
    Python学习笔记——字典(dict)
  • 原文地址:https://www.cnblogs.com/chenyang920/p/4739007.html
Copyright © 2020-2023  润新知