評測ID: 3180536
用戶名: FMM
狀態: 測試通過
Accepted
得分 : 100
總時間耗費: 550ms
總內存耗費: 4
MB
測試點#ask1.in 結果: 內存使用量: 256kB 時間使用量: 1ms
測試點#ask10.in 結果: 內存使用量: 4328kB 時間使用量: 174ms測試點#ask2.in 結果: 內存使用量: 128kB 時間使用量: 1ms
測試點#ask3.in 結果: 內存使用量: 1896kB 時間使用量: 21ms
測試點#ask4.in 結果: 內存使用量: 2156kB 時間使用量: 79ms
測試點#ask5.in 結果: 內存使用量: 2156kB 時間使用量: 78ms
測試點#ask6.in 結果: 內存使用量: 4332kB 時間使用量: 174ms
測試點#ask7.in 結果: 內存使用量: 128kB 時間使用量: 2ms
測試點#ask8.in 結果: 內存使用量: 128kB 時間使用量: 1ms
測試點#ask9.in 結果: 內存使用量: 1772kB 時間使用量: 19ms
用兩個樹狀數組維護兩個數值之間的差時間區間修改與區間查詢
#include <cstdio>
using namespace std;
long long tr[200005],tr_[200005];
int m,n,q,w,e,k,lst;
inline int lowbit(int x){return x&-x;}
void add(int q,int d)
{
int x=q;
while (x<=n)
{
tr[x]+=d;
tr_[x]+=d*q;
x+=lowbit(x);
}
return;
}
long long query(int q)
{
long long ans=0,x=q;
while (x>0)
{
ans+=(q+1)*tr[x]-tr_[x];
x-=lowbit(x);
}
return ans;
}
int main(void)
{
scanf("%d",&n);
for (register int i=1;i<=n;++i)
{
scanf("%d",&q);
add(i,q-lst);
lst=q;
}
scanf("%d",&m);
for (register int i=1;i<=m;++i)
{
scanf("%d",&k);
if (k==1)
{
scanf("%d%d%d",&q,&w,&e);
add(q,e),add(w+1,-e);
}
else
if (k==2)
{
scanf("%d%d",&q,&w);
printf("%lld\n",query(w)-query(q-1));
}
}
return 0;
}
/******************************************************/
2017.10.11
新的做法
似乎並不需要差值
但同樣要用到兩個樹狀數組
似乎可以快一點
評測ID: 3190661
用戶名: FMM
狀態: 測試通過
Accepted
得分 : 100
總時間耗費: 312ms
總內存耗費: 5
MB
測試點#ask1.in 結果: 內存使用量:
256kB 時間使用量: 0ms
測試點#ask10.in 結果: 內存使用量:
5992kB 時間使用量: 109ms
測試點#ask2.in 結果: 內存使用量:
256kB 時間使用量: 0ms
測試點#ask3.in 結果: 內存使用量:
2540kB 時間使用量: 9ms
測試點#ask4.in 結果: 內存使用量:
3052kB 時間使用量: 41ms
測試點#ask5.in 結果: 內存使用量:
3052kB 時間使用量: 42ms
測試點#ask6.in 結果: 內存使用量:
5868kB 時間使用量: 102ms
測試點#ask7.in 結果: 內存使用量:
256kB 時間使用量: 1ms
測試點#ask8.in 結果: 內存使用量:
256kB 時間使用量: 1ms
測試點#ask9.in 結果: 內存使用量:
2668kB 時間使用量: 7ms
#include <cstdio>
#define C (c=getchar())
#define lowbit(x) (x&-x)
using namespace std;
long long m,n,a[200005],opt,tr[200005],tr_[200005];
inline void read(long long &n)
{
long long f=1;char c;n=0;C;
while (c<'0'||c>'9') c=='-'?f=-1,C:C;
while (c>='0'&&c<='9') n=(n<<3)+(n<<1)+c-48,C;
return (void)(n*=f);
}
void add(long long q,long long x)
{
long long p=q,w=q*x;
while (p<=n)
{
tr[p]+=x;
tr_[p]+=w;
p+=lowbit(p);
}
return;
}
long long query(long long x)
{
long long p=x,sum=0,sum_=0;
while (p>0)
{
sum+=tr[p];
sum_+=tr_[p];
p-=lowbit(p);
}
return (x+1)*sum-sum_;
}
int main(void)
{
long long q,w,e;
read(n);
for (register long long i=1;i<=n;++i) read(a[i]),a[i]+=a[i-1];
read(m);
for (register long long i=1;i<=m;++i)
{
read(opt);
if (opt==1)
{
read(q),read(w),read(e);
add(q,e),add(w+1,-e);
}
else
{
read(q),read(w);
printf("%lld\n",a[w]+query(w)-a[q-1]-query(q-1));
}
}
return 0;
}