HDU4027 Can you answer these queries? 线段树

这道题最坑的一点就是a,b大小关系不确定。。。另外如果区间内的所有数都是1就不必更新了,不然挨个更新叶子节点会TLE。。

改线段树的时候不是很敢改,但是看过标程发现还是要胆大一些。主要是区间更新,以前是一段更新,现在是以点更新;另外不需要用懒标记。不多说了,直接上AC代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
typedef pair<ll,ll>pp;
#define mkp make_pair
#define pb push_back
const ll INF=0x3f3f3f3f;
const ll MOD=1e9+7ll;

const ll MAX=100005;
int n,q;
ll ans;
struct node
{
    ll l,r,w,f;
}tree[4*MAX];

void push_up(int k)
{
    tree[k].w=tree[k<<1].w+tree[k<<1|1].w;
}
void build(int k,int l,int r)
{
    tree[k].l=l,tree[k].r=r;
    //tree[k].f=0;
    if(tree[k].l==tree[k].r)
    {   scanf("%lld",&tree[k].w);   return; }
    ll m=(tree[k].l+tree[k].r)>>1;
    build(k<<1,l,m);
    build(k<<1|1,m+1,r);
    push_up(k);
}

void change_interval(int k,int a,int b,int y) //区间修改
{//如果区间内的所有数都是1就不必更新了,否则挨个更新叶子
    if(tree[k].l==tree[k].r)
    {
        tree[k].w=sqrt(1.0*tree[k].w);
        return;
    }
    /*if(tree[k].l>=a&&tree[k].r<=b)
    {
        tree[k].w+=(tree[k].r-tree[k].l+1)*y;
        tree[k].f+=y;
        return;
    }*/
    if(tree[k].l>=a&&tree[k].r<=b&&(tree[k].w==tree[k].r-tree[k].l+1))//区间内的所有数都是1
        return;
    //if(tree[k].f)  down(k);
    ll m=(tree[k].l+tree[k].r)>>1;
    if(a<=m)  change_interval(k<<1,a,b,y);
    if(b>m)  change_interval(k<<1|1,a,b,y);
    push_up(k);
}
void ask_interval(int k,int a,int b) //区间查询
{
    if(tree[k].l>=a&&tree[k].r<=b)
    {   ans+=tree[k].w;   return;  }
    //if(tree[k].f)  down(k);
    ll m=(tree[k].l+tree[k].r)>>1;
    if(a<=m)  ask_interval(k<<1,a,b);
    if(b>m)  ask_interval(k<<1|1,a,b);
}

int main()
{
    int a,b;
    int tt=0;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,1,n);
        scanf("%d",&q);
        int c;
        tt++;printf("Case #%d:\n",tt);
        while(q--)
        {
            scanf("%d%d%d",&c,&a,&b);
            int tmp=min(a,b);//WA点!!!!!
            b=max(a,b);
            a=tmp;
            if(c==0)//区间修改
            {
                change_interval(1,a,b,1);
            }
            else //区间查询
            {
                ans=0;
                ask_interval(1,a,b);
                printf("%lld\n",ans);
            }
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Cc_Sonia/article/details/82597494