【CSP201709-5】除法

来源:互联网 发布:2017北京程序员工资 编辑:程序博客网 时间:2024/06/01 08:07

问题描述

       小葱喜欢除法,所以他给了你N个数a1, a2, ⋯, aN,并且希望你执行M次操作,每次操作可能有以下两种:

  给你三个数l, r, v,你需要将al, al+1, ⋯, ar之间所有v的倍数除以v。
  给你两个数l, r,你需要回答al + al+1 + ⋯ + ar的值是多少。
  
输入格式
  第一行两个整数N, M,代表数的个数和操作的次数。
  接下来一行N个整数,代表N个数一开始的值。

输出格式
  对于每一次的第二种操作,输出一行代表这次操作所询问的值。
样例输入

5 31 2 3 4 52 1 51 1 3 22 1 5

样例输出

1514

评测用例规模与约定
  对于30%的评测用例,1 ≤ N, M ≤ 1000;
  对于另外20%的评测用例,第一种操作中一定有l = r;
  对于另外20%的评测用例,第一种操作中一定有l = 1 , r = N;
  对于100%的评测用例,1 ≤ N, M ≤ 105,0 ≤ a1, a2, ⋯, aN ≤ 106, 1 ≤ v ≤ 106, 1 ≤ l ≤ r ≤ N。


解题思路:考试的时候数据类型写错了,其实得50分的思路很简单,直接算就是了,不过想得满分还是得用点技巧,这个熟悉树状数组的应该很快就能写出来,树状数组在这里有介绍http://blog.csdn.net/nininicrystal/article/details/78656755

code:

#include <bits/stdc++.h>using namespace std;//50分/*void fun1(int l,int r,long long v,long long a[]){    for(int i=l;i<=r;i++)    {        if(a[i]%v==0)            a[i]/=v;    }}long long fun2(int l,int r,long long a[]){    long long ans=0;    int i=l,j=r;    while(i<j)    {        ans+=(a[i]+a[j]);        i++;        j--;    }    if(i==j)        ans+=a[i];    return ans;}int main(){    int n,m,op,l,r;    long long v,a[100005];    cin>>n>>m;    memset(a,0,sizeof(a));    for(int i=1;i<=n;++i)        cin>>a[i];    for(int i=0;i<m;i++)    {        cin>>op;        if(op==1)        {            cin>>l>>r>>v;            fun1(l,r,v,a);        }        else if(op==2)        {            cin>>l>>r;            cout<<fun2(l,r,a)<<endl;        }    }    return 0;}*/long long tree[101024];int n,m,a[101024];int lowbit(int x){    return -x&x;}void update(int x,int v){    for(int i=x;i<=n;i+=lowbit(i))        tree[i]+=v;}long long getsum(int x){    long long ans =0;    for(int i=x;i>0;i-=lowbit(i))        ans+=tree[i];    return ans;}int main(){    int op,l,r;    int v;    cin>>n>>m;    for(int i=1;i<=n;++i)    {        cin>>a[i];        update(i,a[i]);    }    for(int i=0;i<m;i++)    {        cin>>op;        if(op==1)        {            cin>>l>>r>>v;            if(v==1)                continue;            while(l<=r)            {                if(a[l]>=v&&a[l]%v==0)                {                    update(l,-(a[l]-a[l]/v));                    a[l]/=v;                }                ++l;            }        }        else if(op==2)        {            cin>>l>>r;            cout<<getsum(r)-getsum(l-1)<<endl;        }    }    return 0;}


原创粉丝点击