ACM_线段树模板(区间更新)

来源:互联网 发布:仁爱路99号碧格网络 编辑:程序博客网 时间:2024/06/06 00:47

first code(求总和):

#include <iostream>#include <bits/stdc++.h>using namespace std;#define lchild left, mid, root<<1#define rchild mid+1, right, root<<1|1#define maxn 100100int lazy[maxn<<2];int sum[maxn<<2];void update(int root){    sum[root] = sum[root<<1]+sum[root<<1|1];}void lazyup(int root, int sub){    if (lazy[root])    {        lazy[root<<1] = lazy[root<<1|1] = lazy[root];        sum[root<<1] = (sub-sub/2)*lazy[root];        sum[root<<1|1] = (sub/2)*lazy[root];        lazy[root] = 0;    }}void build(int left, int right, int root){    lazy[root] = 0;    sum[root] = 1;    if (left==right)        return;    int mid  = (left+right)>>1;    build(lchild);    build(rchild);    update(root);}void operate(int l, int r, int c, int left, int right, int root){    if (l<=left&&r>=right)    {        lazy[root] = c;        sum[root] = c*(right-left+1);        return;    }    lazyup(root, right-left+1);    int mid = (left+right)>>1;    if (l<=mid)        operate(l,r,c,lchild);    if (r>mid)        operate(l,r,c,rchild);    update(root);}int main(){    int N,n,m;    cin>>N;    int t=N;    while (N--)    {        scanf("%d%d",&n,&m);        build (1,n,1);        while (m--)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            operate(a,b,c,1,n,1);        }        printf("Case %d: The total value of the hook is %d.\n", t-N, sum[1]);    }    return 0;}

second code(求每个) :

#include <iostream>#include <bits/stdc++.h>using namespace std;int ans[1000000],n;struct node{    int l,r,n;}a[1000000];void build(int left, int right ,int root){    a[root].l = left;    a[root].r = right;    a[root].n = 0;    if (left!=right)    {        int mid = (left+right)>>1;        build(left, mid, root<<1);        build(mid+1, right, root<<1|1);    }}void operate(int left, int right, int root){    if (a[root].l==left&&a[root].r==right)    {        a[root].n++;    }    else    {        int mid  = (a[root].l+a[root].r)>>1;        if (right<=mid)        {            operate(left,right,root<<1);        }        else if(left>mid)        {            operate(left,right,root<<1|1);        }        else        {            operate(left,mid,root<<1);            operate(mid+1,right,root<<1|1);        }    }}void add(int root){    int i;    for(i = a[root].l; i<=a[root].r; i++)//该区间所有编号都被刷了一次        ans[i]+=a[root].n;    if(a[root].l == a[root].r)        return;    add(root<<1);    add(root<<1|1);}int main(){    int n,i,j;    while (scanf("%d",&n),n!=0)    {        build(1,n,1);        int x,y;        for(int i = 1; i<=n; i++)        {            scanf("%d%d",&x,&y);            operate(x,y,1);        }        memset(ans,0,sizeof(ans));        add(1);        printf("%d",ans[1]);        for(i = 2; i<=n; i++)            printf(" %d",ans[i]);        printf("\n");    }    return 0;}