BUOJ C 简单的除法 (前缀积+后缀积)

C 简单的除法

时间限制:1000ms   内存限制:131072kb

通过率:18/35 (51.43%)    正确率:18/155 (11.61%)

题目描述

除法是一种简单的运算除法可以看成乘法的逆运算,也可以理解为重复的减法。例如,由 23=6 2∗3=6 可得 6÷2=3 6÷2=3 6÷3=2 6÷3=2,下面我们就来做一些除法练习吧。

给定一个数列 a1,a2,,an a1,a2,⋯,an,令 S=a1a2an S=a1∗a2∗⋯∗an,有 q q 个询问,每个询问包含一个整数 k k,求 (S÷ak)mod232 (S÷ak)mod232

输入

第一行包含一个正整数 T T,表示有 T T 组测试数据。

接下来依次给出每组测试数据。对于每组测试数据:

第一行包含两个整数 n n q q,含义见题目描述。

第二行包含 n n 个整数,表示 a1,a2,,an a1,a2,⋯,an

接下来 q q 行,每行包含一个正整数 k k,表示一个询问。

保证在一行中的每个整数之间有恰好一个空格,没有其他额外的空格。

保证所有的数据满足 1T20, 1≤T≤20, 1n105, 1≤n≤105, 1q105, 1≤q≤105, 1ai232, 1≤ai≤232, 1kn 1≤k≤n

输出

对于每组数据,输出 q q 行,每行包含一个整数,表示题目所求式子的值。

输入样例

1
2 1
1 2
2

输出样例

1



解析:
其实就是每一次询问问你除掉ak后的数组乘积模上2^32次方是多少

因为乘法对于模运算是有分配律的所以,只要处理出前缀积和后缀积就可以了。
并且注意前缀积和后缀积是要多设两个边界量来处理n=1的情况

#include<cstdio>

#include<cstring>

typedef unsigned long long ull;

const ull MOD = (ull)1<<32;

const int MAXN = 1e5+100;

ull num[MAXN];

ull bef[MAXN];
ull bac[MAXN];

int main()
{
    int t;
    int n,q;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&q);
        bef[0]=1; //求前缀和后缀的和要设两个边界值,因为当n=1的时候要用到这两个边界值
        for(int i=1;i<=n;i++)
        {
            scanf("%llu",&num[i]);
            bef[i]=((bef[i-1]%MOD)*(num[i]%MOD))%MOD;
        }
        bac[n+1]=1;
        for(int i=n;i>=1;i--)
        {
            bac[i]=((bac[i+1]%MOD)*(num[i]%MOD))%MOD;
        }
        int u;
        for(int i=0;i<q;i++)
        {
            scanf("%d",&u);
            printf("%llu\n",((bef[u-1]%MOD)*(bac[u+1]%MOD))%MOD);
        }

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值