說實話,這個題就是一個線段樹或者樹狀數組的裸題,難度放在第五題有點牽強。關鍵是數據還特別水,純暴力可以拿80分!我也是服了!這是我暴力得到的結果:
暴力程序如下,純暴力即可。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e5+10;
int a[N];
int main()
{
int N, M; cin >> N >> M;
for(int i = 1; i <= N; i++) cin >> a[i];
while(M--)
{
int opt; cin >> opt;
if(opt==1)
{
int l, r, v; cin >> l >> r >> v;
if(v==1) continue;
for(int i = l; i <= r; i++)
if(a[i]%v==0) a[i]/=v;
}
else
{
int l, r; cin >> l >> r;
long long res = 0;
for(int i = l; i <= r; i++)
res += a[i];
cout << res << endl;
}
}
return 0;
}
正解用樹狀數組,程序如下:
#include <iostream>
using namespace std;
const int maxn = 100005;
int N, M;
int a[maxn]; // 存放原始數據
long long c[maxn]; // 存放樹狀數組
void add(int i, int value)
{
while (i<=N)
{
c[i] += value;
i += i&(-i);
}
}
long long sum(int i)
{
long long sum = 0;
while (i>0)
{
sum += c[i];
i -= i&(-i);
}
return sum;
}
int main()
{
cin >> N >> M;
for (int i = 1; i <= N; ++i) cin >> a[i], add(i, a[i]);
while(M--)
{
int opt, l, r, v; cin >> opt >> l >> r;
if (opt==2) cout << sum(r)-sum(l-1) << endl;
else
{
cin >> v;
if (v==1) continue; // 不處理除以1這種情況會超時
for (int j = l; j <= r; ++j){
if (a[j]>=v && a[j]%v==0) // 不加上a[j]>v會超時
{
add(j, -(a[j]-a[j]/v)); // 用加法代替除法a[j]/v = a[j]-(a[j]-a[j]/v)
a[j] = a[j]/v;
}
}
}
}
return 0;
}