记录,最近我大HDU进不去没法判 但是!样例过了(手动滑稽)
这题也是经典题了单点修改区间查询,这个地方我老是段错误,然后改的时候发现查询的特判错了,之后发现和样例还是不一样不同的共同点在于都是没有加上区间的第一个点。然后找到错误在于当要查询的区间完全在当前区间左边和完全在区间右边时的判断有小段重复。
#include <iostream>
#include<string>
#include <algorithm>
#include <string.h>
#include<cstdio>
#include <sstream>
using namespace std;
struct xian
{
int l,r,da;
} a[500000];
int father[500000],jk[500000];
void build(int k,int l,int r)
{
a[k].l=l,a[k].r=r;
a[k].da=0;
if(l==r)
{
a[k].da=jk[l];
return;
}
int mind=(l+r)>>1;
build(2*k,l,mind),build(2*k+1,mind+1,r);
a[k].da=a[2*k].da+a[2*k+1].da;
}
void change(int k,int num,int data)
{
if(a[k].l==a[k].r)
{
a[k].da+=data;
return ;
}
int mid=(a[k].l+a[k].r)>>1;
if(num<=mid)
change(2*k,num,data);
else
change(2*k+1,num,data);
a[k].da=a[2*k].da+a[2*k+1].da;
}
int searcha(int k,int l,int r)
{
if(a[k].l==l&&a[k].r==r)
return a[k].da;
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid)
return searcha(2*k,l,r);
if(l>mid)//严重标注 就是这我多加了个等号。这样它的左端点是在左半区间可是加下来找的是右区间
return searcha(2*k+1,l,r);
return searcha(2*k,l,mid)+searcha(2*k+1,mid+1,r);
}
int main()
{
int n,m,ll,ans=0;
cin>>ll;
while(ll--)
{
ans++;
cin>>n;
for(int i=1; i<=n; i++)
cin>>jk[i];
build(1,1,n);
int l,r;
string k;
printf("Case %d:\n",ans);
while(cin>>k>>l>>r,k[0]!='E')
{
if(k[0]=='A')
{
change(1,l,r);
}
else if(k[0]=='S')
change(1,l,-r);
else if(k[0]=='Q')
{
cout<<searcha(1,l,r)<<endl;
}
}
}
}