HDU 1166 敌兵布阵

传送门:HDU 1166 敌兵布阵
算法分析:线段树模板,注意读入处理


树状数组:

#include<iostream>
#include<cstdio>
#include<cstring>
#define node long long
#define fm(x) memset(x,0,sizeof(x))
#define u(p,x,y,w) p.modify(x,w),p.modify(y+1,-w)
#define q(p,x,y) p.query(y)-p.query(x-1)
#define c(p) p.clear(n)
#define in(x) x=read()
#define rd int
#define f(x,y) for(register int i=x;i<=y;i++)
using namespace std;
const int maxN=100000;
class binary_tree
{
	public:
		void clear(node n) {tot=n; fm(tree1); fm(tree2);}
		void modify(node x,node val) {update(tree1,x,val); update(tree2,x,val*x);}
		node query(node x) {return (x+1)*sum(tree1,x)-sum(tree2,x);}
	private:
		node tree1[maxN+1],tree2[maxN+1],tot;
		inline node lowbit(node x) {return x&(-x);}
		node sum(node a[],node x) {node ans=0; while(x>0) {ans+=a[x]; x-=lowbit(x);} return ans;}
		void update(node a[],node x,node val) {while(x<=tot) {a[x]+=val; x+=lowbit(x);}}
};
int n,m,x,y,w,ls;
char s[6];
binary_tree tree;
void task(int);
int main()
{
	int _times; scanf("%d",&_times);
    f(1,_times) task(i);
    return 0;
}
void task(int cas)
{
    scanf("%d%d",&n,&ls); c(tree);
    tree.modify(1,ls);
    printf("Case %d:\n",cas);
    f(2,n) {scanf("%d",&w); tree.modify(i,w-ls); ls=w;}
    while(true)
    {
        scanf("%s",s);
        if(!strcmp(s,"End")) break;
        scanf("%d%d",&x,&y);
        if(!strcmp(s,"Query")) printf("%lld\n",q(tree,x,y));
        if(!strcmp(s,"Add")) u(tree,x,x,y);
        if(!strcmp(s,"Sub")) u(tree,x,x,-y);
    }
}

线段树

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxN 100000
#define mid ((l+r)>>1)
#define ls k<<1
#define rs k<<1 | 1
using namespace std;
typedef long long ll;
ll sum[4*maxN+1],v[4*maxN+1];
void pushup(int);
void update(int,int,int,int,int,int);
void pushdown(int,int,int);
ll query(int,int,int,int,int);
void build(int,int,int);
int n,x,y,t;
char s[6];
void task(int);
int main()
{
    scanf("%d",&t);
    for(int i=1;i<=t;i++) task(i);
    return 0;
}
void task(int cas)
{
    memset(sum,0,sizeof(sum));
    memset(v,0,sizeof(v));
    scanf("%d",&n); build(1,1,n);
    printf("Case %d:\n",cas);
    while(true)
    {
        scanf("%s",s);
        if(!strcmp(s,"End")) break;
        scanf("%d%d",&x,&y);
        if(!strcmp(s,"Query")) printf("%lld\n",query(1,1,n,x,y));
        if(!strcmp(s,"Add")) update(1,1,n,x,x,y);
        if(!strcmp(s,"Sub")) update(1,1,n,x,x,-y);
    }
}
void pushup(int k) {sum[k]=sum[ls]+sum[rs];}
void update(int k,int l,int r,int ql,int qr,int u)
{
    if(ql<=l && r<=qr)
    {
        sum[k]+=u*(r-l+1);
        v[k]+=u; return;
    }
    if(v[k]) pushdown(k,l,r);
    if(ql<=mid) update(ls,l,mid,ql,qr,u);
    if(qr>mid) update(rs,mid+1,r,ql,qr,u);
    pushup(k);
}
ll query(int k,int l,int r,int ql,int qr)
{
    if(ql<=l && r<=qr) return sum[k];
    if(v[k]) pushdown(k,l,r);
    long long ans=0;
    if(ql<=mid) ans+=query(ls,l,mid,ql,qr);
    if(qr>mid) ans+=query(rs,mid+1,r,ql,qr);
    return ans;
}
void build(int k,int l,int r)
{
    if(l==r) {scanf("%lld",&sum[k]); return;}
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(k);
}
void pushdown(int k,int l,int r)
{
    v[ls]+=v[k]; v[rs]+=v[k];
    sum[ls]+=(mid-l+1)*v[k];
    sum[rs]+=(r-mid)*v[k];
    v[k]=0;
}
posted @ 2019-02-10 10:56  常青藤的花语  阅读(132)  评论(0编辑  收藏  举报

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。