4 条题解

  • 2
    @ 2025-12-7 11:26:34

    阎帝小代码

    #include<bits/stdc++.h>
    #define int long long
    #define lc(p) (p<<1)
    #define rc(p) (p<<1|1)
    using namespace std;
    const int N=6e5+10;//不清楚为什么要开6e5,我开5e5就RE 
    struct node{int l,r,sum;}t[N<<2];
    int a[N],n,q;
    void pu(int p){t[p].sum=t[lc(p)].sum+t[rc(p)].sum;}
    void build(int id,int l,int r)
    {
    	t[id]={l,r,0};
    	if(l==r){t[id].sum=a[l];return ;}
    	int m=l+r>>1;
    	build(lc(id),l,m);build(rc(id),m+1,r);
    	pu(id);
    }
    void change(int p,int x,int y)
    {
    	if(x<t[p].l||x>t[p].r)return ;
    	t[p].sum+=y;
    	change(lc(p),x,y);change(rc(p),x,y);
    }
    int query(int p,int l,int r)
    {
    	if(r<t[p].l||t[p].r<l)return 0;
    	if(l<=t[p].l&&t[p].r<=r)return t[p].sum;
    	return query(lc(p),l,r)+query(rc(p), l,r);
    }
    signed main()
    {
    	scanf("%lld%lld",&n,&q);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    	build(1,1,n);
    	while(q--)
    	{
    		int op,x,y;scanf("%lld%lld%lld",&op,&x,&y);x++;
    		if(op==0)
    		{
    			change(1,x,y);
    		}
    		else
    		{
    			printf("     %lld\n",query(1,x,y));
    		}
    	}
    	return 0;
    }
    
    
    • 1
      @ 2026-8-2 10:52:47

      点修区查,这不树状数组板子吗。

      注意下标需要整体加 11,树状数组本身不支持下标 00 作为有效操作节点。

      提交记录:626ms,8 MiB这不比线段树香吗

      #include<bits/stdc++.h>
      using namespace std;
      #define int ll
      #define In inline
      #define ll long long 
      #define rep(i,x,y) for(int i=x;i<=y;++i)
      #define per(i,x,y) for(int i=x;i>=y;--i)
      In void ios_off(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
      const int N=5e5+10;
      int n,q,c[N];
      int lowbit(int x){return x&-x;}
      void add(int x,int k){for(;x<=n;x+=lowbit(x))c[x]+=k;}
      int query(int x)
      {
      	int res=0;
      	for(;x;x-=lowbit(x))res+=c[x];
      	return res;
      }
      signed main()
      {
      	ios_off();
      	cin>>n>>q;
      	rep(i,1,n)
      	{
      		int x;cin>>x;
      		add(i,x);
      	}
      	rep(i,1,q)
      	{
      		int op;cin>>op;
      		if(op==0)
      		{
      			int p,x;cin>>p>>x;
      			add(p+1,x);
      		}
      		else
      		{
      			int l,r;cin>>l>>r;
      			cout<<query(r)-query(l)<<'\n';
      		}
      	}
      	return 0;
      }
      
      • 1
        @ 2026-7-15 15:35:22

        你是说不想在以后出现函数名重复的情况?

        那就试试结构体吧!!!

        线段树:

        #include<bits/stdc++.h>
        using namespace std;
        #define int long long
        const int N=5e5+10;
        int a[N];
        #define lc(p) (p<<1)
        #define rc(p) (p<<1|1)
        struct node{int l,r,s;};
        struct SMT{
        	node tr[N<<2];
        	void pushup(int p){tr[p].s=tr[lc(p)].s+tr[rc(p)].s;}
        	void bt(int p,int l,int r)
        	{
        		tr[p]={l,r,0};
        		if(l==r){tr[p].s=a[l];return;}
        		int mid=(l+r)>>1;
        		bt(lc(p),l,mid);bt(rc(p),mid+1,r);
        		pushup(p);
        	}
        	void change(int p,int x,int k)
        	{
        		if(tr[p].l>x||tr[p].r<x)return ;
        		if(tr[p].l==tr[p].r)
        		{
        			tr[p].s+=k;
        			return;
        		}
        		change(lc(p),x,k);change(rc(p),x,k);
        		pushup(p);
        	}
        	int query(int p,int l,int r)
        	{
        		if(tr[p].l>r||tr[p].r<l)return 0;
        		if(l<=tr[p].l&&tr[p].r<=r)return tr[p].s;
        		return query(lc(p),l,r)+query(rc(p),l,r);
        	}
        }tr;
        #undef lc(p)
        #undef rc(p)
        signed main()
        {
        	int n,q;cin>>n>>q;
        	for(int i=1;i<=n;i++)cin>>a[i];
        	tr.bt(1,1,n);
        	while(q--)
        	{
        		int op,x,y;cin>>op>>x>>y;
        		if(op==0)tr.change(1,x+1,y);
        		else cout<<tr.query(1,x+1,y)<<'\n';
        	}
        	return 0;
        }
        

        树状数组:

        #include<bits/stdc++.h>
        using namespace std;
        #define int long long
        const int N=5e5+10;
        struct BIT{
        	int c[N],n;
        	void add(int x,int k){for(;x<=n;x+=x&-x)c[x]+=k;}
        	int ask(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
        }tr;
        int a[N];
        signed main()
        {
        	int n,q;cin>>n>>q;tr.n=n;
        	for(int i=1;i<=n;i++)cin>>a[i],tr.add(i,a[i]);
        	while(q--)
        	{
        		int op,x,y;cin>>op>>x>>y;
        		if(op==0)tr.add(x+1,y);
        		else cout<<(tr.ask(y)-tr.ask(x))<<'\n';
        	}
        	return 0;
        }
        
        • 1
          @ 2026-2-11 10:15:22
          #include<bits/stdc++.h>
          using namespace std;
          #define lc(p) (p << 1)      /*i的左孩子编号为i*2*/
          #define rc(p) (p << 1 | 1)  /*i的右孩子编号为i*2+1*/
          const int N = 6e5 + 10;
          #define int long long
          int a[N];/*记录数组初值*/
          struct node
          {int l/*左区间*/, r/*右区间*/, v/*区间最小值*/;}tr[N << 2]/*开四倍, 防炸*/;
          void pushup(int p){tr[p].v = tr[lc(p)].v + tr[rc(p)].v;}/*更新节点权值*/
          void build(int p, int l, int r)/*节点p管理区间[l,r]构造线段树*/
          {
              tr[p] = {l, r, 0};/*赋值节点p*/
          if (l == r)/*如果只管理一个点*/
                  {tr[p].v = a[l];/*直接赋值权值*/ return;/*已经到最低层了*/ }
              int mid = (l + r) >> 1;
              build(lc(p), l, mid);/*左孩子管理p管理范围的左半边*/
              build(rc(p), mid + 1, r);/*右孩子管理剩下右半边*/
              pushup(p);/*递归回来时更新p的区间和*/
          }
          int query(int p, int l, int r)/*查询区间[l,r]的区间和*/
          {
              if (r < tr[p].l or tr[p].r < l)/*如果p管理区间与[l,r]无关*/
                  return 0;/*对答案贡献为0*/
              if (l <= tr[p].l and tr[p].r <= r)/*p区间在区间[l,r]内*/
                  return tr[p].v;/*不会贡献区间以外的答案, 直接返回p的权值*/
          
              /*如果p包括了查询区间以外的值, 就将区间细分到左右儿子再统计*/
              return query(lc(p), l, r) + query(rc(p), l, r);
          }
          void change(int p, int x, int y)/*将a[x]的值加上y*/
          {
              if (x < tr[p].l or tr[p].r < x)/*如果x不在p管理区间内*/
                  return;
              tr[p].v += y;/*如果x在p管理区间内, p的区间和加y*/
              change(lc(p), x, y); change(rc(p), x, y);/*递归修改左右孩子的区间和*/
          }
          signed main()
          {
              int n, q; cin >> n >> q;
              for (int i = 1; i <= n; i++) cin >> a[i];
              build(1, 1, n);
              while (q--)
              {
                  int op, x, y; cin >> op >> x >> y;
                  x ++;
                  if (op == 0)
                      change(1, x, y);
                  else
                      cout << query(1, x, y) << '\n';
              }
              return 0;
          }
          
          #include<bits/stdc++.h>
          using namespace std;
          #define int long long
          #define lc(p) tr[p].ls
          #define rc(p) tr[p].rs
          const int N = 5e5 + 10;
          struct node{int val, ls, rs;}tr[N << 2];
          int trlen = 1, rt, a[N];
          void pushup(int p){tr[p].val = tr[lc(p)].val + tr[rc(p)].val;}
          
          void build(int p, int l, int r)
          {
              tr[p] = {0, 0, 0};
              if (l == r) {tr[p].val = a[l]; return;}
              int mid = (l + r) >> 1;
              lc(p) = ++trlen; build(lc(p), l, mid);
              rc(p) = ++trlen; build (rc(p), mid + 1, r);
              pushup(p);
          }
          
          void change(int p, int l, int r, int k, int x)
          {
              if (l == r) {tr[p].val += x; return; }
              int mid = (l + r) >> 1;
              if (k <= mid) change(lc(p), l, mid, k, x);
              else change(rc(p), mid + 1, r, k, x);
              pushup(p);
          }
          
          int query(int p, int l, int r, int x, int y)
          {
              if (y < l or r < x) return 0;
              if (x <= l and r <= y) return tr[p].val;
              int mid = (l + r) >> 1;
              return query(lc(p), l, mid, x, y) + query(rc(p), mid + 1, r, x, y);
          }
          
          signed main()
          {
              int n, q; cin >> n >> q;
              for (int i = 1; i <= n; i++) cin >> a[i];
              build(1, 1, n);
              while (q--)
              {
                  int op, x, y; cin >> op >> x >> y;
                  if (op == 0) change(1, 1, n, x + 1, y);
                  else if (op == 1) cout << query(1, 1, n, x + 1, y) << endl;
              }
              return 0;
          }
          
          • 1

          点加区间和(Point Add Range Sum)

          信息

          ID
          8126
          时间
          1000ms
          内存
          1024MiB
          难度
          6
          标签
          递交数
          55
          已通过
          16
          上传者