您的位置:首页 > 其它

【生活没有希望】hdu1166敌兵布阵 线段树

2016-08-11 13:31 357 查看
线段树水题刷刷,生活没有希望

最近看到代码跟树状数组差不多短的非递归线段树,常数也很小——zkw线段树

于是拿道水题练练手

短到让人身无可恋

void add(int pos,int x){    for(pos+=M+1;pos;pos/=2)    a[pos]+=x;}
int que(int l,int r){    for(l+=M,r+=M+2,ans=0;l^r^1;l>>=1,r>>=1)ans+=((l&1)?0:a[l|1])+((r&1)?a[r-1]:0);return ans;}


单点修改和区间查询(通过前缀和可以变成区间修改单点查询,再加特技标记可以变成区间修区间查)

M=1;n+=2;
while(M<n)
M*=2;
M--;
for(int i=1;i<=M+n+1;i++)
a[i]=0;


初始化(赋初值0是因为这道题多组数据,不然还不用)

#include <cstdio>
int t,n,M,p,l,r,ans,a[131073];char ch;
void add(int pos,int x){    for(pos+=M+1;pos;pos/=2)    a[pos]+=x;}
int que(int l,int r){    for(l+=M,r+=M+2,ans=0;l^r^1;l>>=1,r>>=1)ans+=((l&1)?0:a[l|1])+((r&1)?a[r-1]:0);return ans;}
int main()
{
scanf("%d",&t);
for(int T=1;T<=t;T++)
{
printf("Case %d:\n",T);
scanf("%d",&n);
M=1;n+=2;
while(M<n)
M*=2;
M--;
for(int i=1;i<=M+n+1;i++)
a[i]=0;
for(int i=1;i<=n;i++)
scanf("%d",&p),add(i,p);
for(ch=getchar();ch!='E' && ch!='Q' && ch!='A' && ch!='S';ch=getchar());
while(ch!='E')
{
switch(ch)
{
case'Q':
getchar();getchar();getchar();getchar();
scanf("%d%d",&l,&r);printf("%d\n",que(l,r));
break;
case 'A':
getchar();getchar();
scanf("%d%d",&l,&r);add(l,r);
break;
case 'S':
getchar();getchar();
scanf("%d%d",&l,&r);add(l,-r);
break;
}
for(ch=getchar();ch!='E' && ch!='Q' && ch!='A' && ch!='S';ch=getchar());
}
getchar();getchar();
}
return 0;
}


这道水题理论上不需要常数那么小,但是代码短所以还是这么打了

主程序基本都是在输入输出,,,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: