您的位置:首页 > 其它

codeforces 296C

2013-07-15 23:23 471 查看
题目

两颗线段树,一颗用来统计每一次操作的次数,一颗就是寻常的统计求和的线段树。

学会了在结构体中构造多颗线段树的方法,因为建统计次数的线段树时,一直以n来建,导致wa了很多次。

代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 100005

struct Tree
{
    int l,r;
    __int64 num,lazy;
};

struct Command
{
    int l,r;
    __int64 d;
}Com[maxn<<1];

struct Segtree{
    Tree tree[maxn<<2];
    int nu[maxn<<1];
    void PushUp(int rt)
    {
        tree[rt].num=tree[rt<<1].num+tree[rt<<1|1].num;
    }

    void PushDown(int rt)
    {
        if(tree[rt].lazy){
            tree[rt<<1].num+=tree[rt].lazy*(tree[rt<<1].r-tree[rt<<1].l+1);
        tree[rt<<1|1].num+=tree[rt].lazy*(tree[rt<<1|1].r-tree[rt<<1|1].l+1);
        tree[rt<<1].lazy+=tree[rt].lazy;
        tree[rt<<1|1].lazy+=tree[rt].lazy;
        tree[rt].lazy=0;
        }
    }

    void build(int l,int r,int rt)
    {
        tree[rt].l=l;
        tree[rt].r=r;
        tree[rt].lazy=0;
        tree[rt].num=0;
        if(l==r){
            tree[rt].num=nu[l];
            return ;
            }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        PushUp(rt);
    }

    void update(int x,int y,__int64 val,int rt)
    {
        int l,r;
        l=tree[rt].l;
        r=tree[rt].r;
        if(l==x&&r==y){
            tree[rt].lazy+=val;
            tree[rt].num+=val*(tree[rt].r-tree[rt].l+1);
            return ;
            }
        PushDown(rt);
        int m=(l+r)>>1;
        if(x<=m) update(x,min(y,m),val,rt<<1);
        if(y>m) update(max(m+1,x),y,val,rt<<1|1);
        PushUp(rt);
    }

    __int64 query(int pos,int rt)
    {
        int l,r;
        l=tree[rt].l;
        r=tree[rt].r;
        if(l==r) return tree[rt].num;
        PushDown(rt);
        __int64 ans=0;
        int m=(l+r)>>1;
        if(pos<=m) return query(pos,rt<<1);
        else return query(pos,rt<<1|1);
    }
}a,b;
int main()
{
     int i,k,n,m;
     while(~scanf("%d%d%d",&n,&m,&k)){
         for(i=1;i<=n;i++){
             scanf("%d",&a.nu[i]);
         }
         memset(b.nu,0,sizeof(b.nu));
         a.build(1,n,1);
         b.build(1,m,1);
         for(i=1;i<=m;i++){
             scanf("%d%d%I64d",&Com[i].l,&Com[i].r,&Com[i].d);
         }
         int x,y;
         for(i=1;i<=k;i++){
             scanf("%d%d",&x,&y);
             b.update(x,y,1,1);
         }
         for(i=1;i<=m;i++){
             __int64 temp=b.query(i,1);
             a.update(Com[i].l,Com[i].r,Com[i].d*temp,1);
         }
         for(i=1;i<=n;i++){
             __int64 ans=a.query(i,1);
             printf("%I64d ",ans);
         }
         printf("\n");
     }
     return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: