Potentiometers 模板题,就是输出格式很坑

本文探讨了数据结构中的单点修改与区间求和问题,通过树状数组和线段树两种方法实现高效的数据更新与查询操作。树状数组部分展示了如何进行单点更新并快速计算指定区间的元素总和;线段树部分则提供了另一种解决同一问题的思路,通过递归构建和维护树结构,实现区间查询和单点更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单点修改,区间求和,立即推 树状数组

顺便练习一下线段树

树状数组 

#include<bits/stdc++.h>
using namespace std;
//int sev[10000];
typedef long long ll;
const int ma=200001;
int p[4*ma];
long long  sum[4*ma];
ll suma;
    int t;

int lowerbit(int x)
{
    return x&(-x);
}


ll qsum(int x)
{
    ll res=0;
    while(x>0)
    {
        res+=sum[x];
        x-=lowerbit(x);
    }
    return res;
}

void add(int x,ll d){
    
    while(x<=t)
    {
        sum[x]+=d;
        x+=lowerbit(x);
    }
}


int main()
{


    int cou=0;
    while(scanf("%d",&t) && t!=0)
    {
        memset(p,0,sizeof p);
        memset(sum,0,sizeof sum);


        for(int i=1;i<=t;i++)
        {
            scanf("%d",&p[i]);
            add(i,p[i]);
        }



        if(cou!=0){
                printf("\n");
               }


    printf("Case %d:\n",++cou);


        char c[10];
        while(scanf("%s",c) ){
            if(c[0]=='M'){
                suma=0;
                int a, b;
                scanf("%d%d",&a,&b);

                suma=qsum(b)-qsum(a)+p[a];
                printf("%lld\n",suma);
            }

            if(c[0]=='S')
            {
                int a,b;    scanf("%d%d",&a,&b);

                add(a,(ll)(-1*p[a]));
                p[a]=b;
                add(a,(ll)b);
            }

            if(c[0]=='E'){   break;}
        }

    }
    return 0;
}

线段树

#include<bits/stdc++.h>
using namespace std;
//int sev[10000];
const int ma=200001;
int p[4*ma];
long long  sum[4*ma];
long long suma;
void maintain(int o,int l,int r){
    sum[o]=0;
    if(l==r) sum[o]=p[o] ;
    else
    sum[o]=sum[o*2]+sum[o*2+1];
}

void build(int o,int l,int r,int L,int R ,int pot){
    if(L <=l && r<=R)
    {
        p[o]=pot;

    }
    else{

    int m=(l+r)/2;
    if(L<=m)
        build(o*2,l,m,L,R,pot);
    if(m<R)
        build(o*2+1,m+1,r,L,R,pot);

    }

    maintain(o,l,r);
}




void quiry(int o,int l,int r,int L,int R){
    if(L<=l && r<=R)
       {
         suma+=sum[o];
        return ;
       }
    int m=(l+r)/2;
        if(L<=m)
            quiry(o*2,l,m,L,R);
        if(m<R)
            quiry(o*2+1,m+1,r,L,R);
}



int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);

    int t;
    int cou=0;
    while(scanf("%d",&t) && t!=0)
    {


        for(int i=1;i<=t;i++)
        {
            int  pot;   scanf("%d",&pot);
            build(1,1,t,i,i,pot);
        }
        if(cou!=0){
                printf("\n");
               }


    printf("Case %d:\n",++cou);


        char c[10];
        while(scanf("%s",c) ){
            if(c[0]=='M'){
                suma=0;
                int a, b;
                scanf("%d%d",&a,&b);
                quiry(1,1,t,a,b);   // 求 a--b 的和
                printf("%lld\n",suma);
            }

            if(c[0]=='S')
            {
                int a,b;    scanf("%d%d",&a,&b);
                build(1,1,t,a,a,b);     // 在a 处改成b
            }

            if(c[0]=='E'){   break;}
        }

    }
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值