"C a b c" means adding c to each of
Aa, Aa+1, ... ,
Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of
Aa, Aa+1, ... ,
Ab.
思路:很典型的线段树 开始我用普通的线段树做 updata 操作是每一对应的区间都加上w 结果TLE
问了一下zcube 说用什么 线段树遗传(不明白这是个什么??) 上网看了一下别人的解题报告 updata
操作的复杂度太高了(因为我要遍历所有要更新的点 时间复杂度是多少 我不会算
望大牛指点) 然后加了一下优化
//6720K
1579MS
#include <stdio.h>
#define M 100005
struct data
{
l,r;
sum,add;
//两个变量都要用__int64 因为这个WA了几次
} line[3*M];
int num[M];
__int64 ans;
void BuildTree (int left,int right,int u)
{
left;
right;
= 0;
right)
line[u].sum = num[left];
int mid = (line[u].l+line[u].r)/2;
BuildTree(left,mid,2*u);
BuildTree(mid+1,right,2*u+1);
line[u].sum = line[2*u].sum + line[2*u+1].sum;
}
void updata (int left,int right,int w,int u)
{
(line[u].l==left&&line[u].r==right)
//区间一样,就退出 不做再遍历其下面的点 省
{
//很多时间
line[u].add += w;
return ;
+= (right-left+1)*w;
(line[u].l+line[u].r)/2;
<= mid)
updata(left,right,w,2*u);
(left >= mid+1)
updata (left,right,w,2*u+1);
updata (left,mid,w,2*u);
updata (mid+1,right,w,2*u+1);
}
void query (int left,int right,int u)
{
line[u].add*(right-left+1);
(line[u].l+line[u].r)/2;
(line[u].l == left&&line[u].r ==
right)
ans += line[u].sum;
(right <= mid)
query(left,right,2*u);
(left >= mid+1)
query(left,right,2*u+1);
query(left,mid,2*u);