zoukankan      html  css  js  c++  java
  • Can you answer these queries? (线段树

    题目

    题意:

      初始给你n个数,通过m个操作,  操作0是使区间范围内的每一个a[i]都变成 根号a[i] ,操作1是查询区间范围内数字的和。

    思路:

      如果一个节点sum[rt]是1的话,根号1还是1,重复遍历这个节点会大大增加计算次数。n和区间左右端点的范围都 <=1e5,所以一个节点最多遍历不超过10次。

      如果这个节点sum[rt]是1,那么标记这个节点vis[rt]=1,说明这个节点以后不用往下遍历了。如果一个节点的左右子节点vis[rt<<1]=1, vis[rt<<1|1]==1,那么vis[rt]=1。注意longlong 以及输入要多空一行。

    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=1e9+7;
    const int INF= 0x3f3f3f3f;
    const int N=1e5+5;
    
    ll add[N<<2],sum[N<<2];
    ll a[N<<1];
    int vis[N<<2];
     
    /*
    struct node
    {
        int v,p;
    }b[N<<2];
    
    bool cmp(node x,node y)
    {
        return x.v<y.v;
    }*/
    
    void push_up(int rt)
    {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
        vis[rt] = vis[rt<<1] & vis[rt<<1|1] ; //左右子节点的vis都是1 父节点才是1 
    }
    /*
    void push_down(int rt,int ln ,int rn)
    {
        if(add[rt])
        {
            add[rt<<1]=add[rt<<1|1]=add[rt];
            sum[rt<<1]=add[rt]*ln;
            sum[rt<<1|1]=add[rt]*rn;
            add[rt]=0;
        }
    }*/
    void Built(int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]=a[l];
            if(sum[rt]<=1) vis[rt]=1;
            return;
        }
        int m=l+r>>1;
        Built(l,m,rt<<1);
        Built(m+1,r,rt<<1|1);
        push_up(rt);
    }
    
    void update(int x,int y,int l,int r,int rt)
    {
        if(l==r)
        {
            sum[rt]= 1LL*sqrt(sum[rt]*1.0);
            if( sum[rt]<=1 ) vis[rt]=1;
            return;
        }
        int m=l+r>>1;
        //push_down(rt,m-l+1,r-m);
        if(x<=m && !vis[rt<<1]) update(x,y,l,m,rt<<1);
        if(m<y && !vis[rt<<1|1]) update(x,y,m+1,r,rt<<1|1);
        push_up(rt);
    }
    
    ll Query(int x,int y, int l,int r,int rt)
    {
        if(x<=l && r<=y)
        {
            return sum[rt];
        }
        int m=l+r>>1;
        //push_down(rt,m-l+1,r-m);
        ll ans=0;
        if(x<=m) ans+=Query(x,y,l,m,rt<<1);
        if(m<y) ans+=Query(x,y,m+1,r,rt<<1|1);
        return ans;
    }
    int main()
    {
        int x,y,c=0,n,m,q;
           while(~scanf("%d",&n) )
           {
               /*for(int i=1;i<=n;i++) scanf("%d",&b[i].v),b[i].p=i;
               sort(b+1,b+1+n,cmp);
            int cnt=0;
            for(int i=1;i<=n;i++)
            {
                if(b[i].v != b[i-1].v)
                    cnt++;
                   a[b[i].p]=cnt;
               }//离散化完毕  */
               for(int i=1;i<=n;i++)  scanf("%lld",&a[i]);
            mem(vis,0);
            mem(sum,0);
               Built(1,n,1);
               scanf("%d",&m);
               printf("Case #%d:
    ",++c);
            while(m--)
            {
                scanf("%d%d%d",&q,&x,&y);
                if(x>y) swap(x,y);
                if(q==0)
                    update(x,y,1,n,1);
                else
                    printf("%lld
    ",Query(x,y,1,n,1) );
            }
            cout<<endl;
        }
       
    }
  • 相关阅读:
    CSS BEM 命名规范简介
    React 端的编程范式
    在React应用程序中用RegEx测试密码强度
    React 中获取数据的 3 种方法及它们的优缺点
    vue props传值常见问题
    如何理解vue中的v-model?
    利用jQuery not()方法选取除某个元素外的所有元素
    初识Nest.js
    react-绑定this并传参的三种方式
    Angular怎么防御xss攻击?
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10308275.html
Copyright © 2011-2022 走看看