版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/han_hhh/article/details/82500339
问题描述
试题编号: | 201709-5 |
试题名称: | 除法 |
时间限制: | 10.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 小葱喜欢除法,所以他给了你N个数a1, a2, ⋯, aN,并且希望你执行M次操作,每次操作可能有以下两种: 输入格式 第一行两个整数N, M,代表数的个数和操作的次数。 输出格式 对于每一次的第二种操作,输出一行代表这次操作所询问的值。 样例输入 5 3 样例输出 15 评测用例规模与约定 对于30%的评测用例,1 ≤ N, M ≤ 1000; |
在树状数组的模板上修改而成,要注意数据范围,以及v==1时的情况
90分,运行超时。看树状数组看的有点晕了,找不出来问题,一会再继续找
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=101024;
LL tree[maxn];
int a[maxn];
LL lowbit(int x)
{
return x&(-x);
}
//修改操作
void change(int x,int h)
{
for(int i=x;i<=maxn;i+=lowbit(i)){
tree[i]+=h;
}
}
//查询操作
LL getsum(int x)
{
LL res=0;
while(x>0){
res+=tree[x];
x-=lowbit(x);
}
return res;
}
int main()
{
int n,m,opt;
scanf("%d%d",&n,&m);//区间长度和询问次数
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);//输入第i个位置的数
change(i,a[i]);//从第i位进行修改树状数组
}
while(m--){
LL l,r,v;
cin>>opt>>l>>r;
if(opt==1){
cin>>v;
if(v==1)
continue;
while(l<=r){
if(a[l]>=v&&a[l]%v==0){
change(l,-(a[l]-a[l]/v));
a[l]/=v;
}
++l;
}
}
else if(opt==2){
printf("%lld\n",getsum(r)-getsum(l-1));//询问[1,temp]区间的和
}
}
return 0;
}