UVALive - 5798

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\n",ans);
            }
        }
        printf("-\n");
    }
    return 0;
}

时间: 2024-08-12 19:46:41

UVALive - 5798的相关文章

UVALive 4848 Tour Belt

F - Tour Belt Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4848 Description Korea has many tourist attractions. One of them is an archipelago (Dadohae in Korean), a cluster of small islands sca

UVALive 6467 Strahler Order 拓扑排序

这题是今天下午BNU SUMMER TRAINING的C题 是队友给的解题思路,用拓扑排序然后就可以了 最后是3A 其中两次RE竟然是因为: scanf("%d",mm); ORZ 以后能用CIN还是CIN吧 QAQ 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostre

UVALive 7077 Little Zu Chongzhi&#39;s Triangles (有序序列和三角形的关系)

这个题……我上来就给读错了,我以为最后是一个三角形,一条边可以由多个小棒组成,所以想到了状态压缩各种各样的东西,最后成功了……结果发现样例过不了,三条黑线就在我的脑袋上挂着,改正了以后我发现N非常小,想到了回溯每个棍的分组,最多分5组,结果发现超时了……最大是5^12 =  244,140,625,厉害呢…… 后来想贪心,首先想暴力出所有可能的组合,结果发现替换问题是一个难题……最后T T ,我就断片了.. 等看了别人的办法以后,我才发现我忽视了三角形的特性,和把数据排序以后的特点. 如果数据从

Gym 100299C &amp;&amp; UVaLive 6582 Magical GCD (暴力+数论)

题意:给出一个长度在 100 000 以内的正整数序列,大小不超过 10^ 12.求一个连续子序列,使得在所有的连续子序列中, 它们的GCD值乘以它们的长度最大. 析:暴力枚举右端点,然后在枚举左端点时,我们对gcd相同的只保留一个,那就是左端点最小的那个,只有这样才能保证是最大,然后删掉没用的. UVaLive上的数据有问题,比赛时怎么也交不过,后来去别的oj交就过了. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&qu

UVALive 6511 Term Project

Term Project Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 651164-bit integer IO format: %lld      Java class name: Main 解题:强连通分量 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1

UVALive 6508 Permutation Graphs

Permutation Graphs Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 650864-bit integer IO format: %lld      Java class name: Main 解题:逆序数 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long l

UVALive 2659+HUST 1017+ZOJ 3209 (DLX

UVALive 2659 题目:16*16的数独.试了一发大白模板. /* * @author: Cwind */ //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include

UVALive 5545 Glass Beads

Glass Beads Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVALive. Original ID: 554564-bit integer IO format: %lld      Java class name: Main Once upon a time there was a famous actress. As you may expect, she played mostly

UVALive 6145 Version Controlled IDE(可持久化treap、rope)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4156 题目拷贝难度大我就不复制了. 题目大意:维护一个字符串,要求支持插入.删除操作,还有输出第 i 次操作后的某个子串.强制在线. 思路1:使用可持久化treap可破,详细可见CLJ的<可持久化数据结构的研究>. 思路2:rope大法好,详见:http