Can you answer these queries? HDU - 4027

Potential energy analysis line tree is such a thing. For some operations, it can only be changed violently without marking, but the results will not be changed after a few operations (the most common is the interval root sign). We can maintain something to indicate whether the interval will change.  

There are two operations: one is to change each number of l~r to the root of the original number; the other is to query the sum of l~r intervals. In this way, the update method is different from the general addition and subtraction of a number, and the lazy flag is not used. If a single point of update is performed every time the interval is updated, the complexity is 1e5*1e5, which will definitely time out, so another one is used here Tags are used to mark whether the node needs to be updated. Through this tag, the update complexity can be reduced from 1e5*1e5 to 7*1e5, so that it can be over (2 ^ 64 open 7 times becomes 1, so it can be considered that the leaf nodes corresponding to these n numbers are updated 7 times at most, and the total complexity of all updates is 7*n).

In addition, this problem is similar to the problem of division of ccf, which uses the idea of potential line tree.

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 100010
#define ls rt*2
#define rs rt*2+1
struct node
{
    int l,r;
    ll sum;
    bool tag;
}tree[4*maxn];
ll a[maxn];
void build(int l,int r,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    if(l==r)
    {
        tree[rt].sum=a[l];
        if(tree[rt].sum==0||tree[rt].sum==1)
            tree[rt].tag=true;
        else
            tree[rt].tag=false;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,ls);
    build(mid+1,r,rs);
    tree[rt].sum=tree[ls].sum+tree[rs].sum;
    tree[rt].tag=tree[ls].tag&&tree[rs].tag;
}
void update(int l,int r,int rt)
{
    if(tree[rt].tag) return ;
    if(tree[rt].l==tree[rt].r)
    {
        tree[rt].sum=sqrt(tree[rt].sum);
        if(tree[rt].sum==1)
        {
            tree[rt].tag=true;
        }
        return ;
    }
    int mid=(tree[rt].l+tree[rt].r)/2;
    if(mid>=r)
    {
        update(l,r,ls);
    }
    else
        if((mid+1)<=l)
            update(l,r,rs);
        else
        {
            update(l,r,ls);
            update(l,r,rs);
        }
    tree[rt].sum=tree[ls].sum+tree[rs].sum;
    tree[rt].tag=tree[ls].tag&&tree[rs].tag;

}
ll query(int l,int r,int rt)
{
    if(tree[rt].l>=l&&tree[rt].r<=r)
    {
        return tree[rt].sum;
    }
    int mid=(tree[rt].l+tree[rt].r)/2;
    ll ans=0;
    if(mid>=r)
    {
        ans=query(l,r,ls);
    }
    else
        if((mid+1)<=l)
            ans=query(l,r,rs);
        else
        {
            ans=query(l,r,ls);
            ans+=query(l,r,rs);
        }
    return ans;
}
int main()
{
    int n,m,mycase=0;
    while(scanf("%d",&n)!=EOF)
    {
        mycase++;
        printf("Case #%d:\n",mycase);
        for(int i=1;i<=n;i++)scanf("%lld",&(a[i]));
        build(1,n,1);
        scanf("%d",&m);
        while(m--)
        {
            int op,l,r;
            scanf("%d %d %d",&op,&l,&r);
            if(l>r)
                swap(l,r);
            if(op==0)
            {
                update(l,r,1);
            }
            else
            {
                printf("%lld\n",query(l,r,1));
            }
        }
        printf("\n");
    }
    return 0;
}

 

Posted by Dang on Mon, 30 Dec 2019 13:09:47 -0800