线段树 (区间修改,单点查询)
https://www.luogu.com.cn/problem/P3368
上代码,对比一下可以发现,区间修改单点查询 和 单点修改区间查询 的add函数和search函数刚好是反的
#include<bits/stdc++.h> #define N 500005 #define endl '\n' #define _for(i,a,b) for(int i=a;i<b;i++) using namespace std; typedef long long ll; struct Node{ int l,r,num; }T[N*4]; int a[N]; ll res; void build(int i,int l,int r){//µÝ¹é½¨Ê÷ T[i].l=l;T[i].r=r; if(l==r){//Èç¹ûÕâ¸ö½ÚµãÊÇÒ¶×Ó½Úµã T[i].num=a[r]; return ; } int mid=(l+r)>>1; build(i*2,l,mid);//·Ö±ð¹¹Ôì×ó×ÓÊ÷ºÍÓÒ×ÓÊ÷ build(i*2+1,mid+1,r); T[i].num= 0;//¸Õ²ÅÎÒÃÇ·¢ÏÖµÄÐÔÖÊreturn ; } void add(int i,int l,int r,int k){ if(T[i].l>=l && T[i].r<=r){//Èç¹ûÕâ¸öÇø¼ä±»ÍêÈ«°üÀ¨ÔÚÄ¿±êÇø¼äÀïÃ棬½²Õâ¸öÇø¼ä±ê¼Çk T[i].num+=k; return ; } if(T[i*2].r>=l) add(i*2,l,r,k); if(T[i*2+1].l<=r) add(i*2+1,l,r,k); } void search(int i,int dis){ res+=T[i].num;//һ·¼ÓÆðÀ´ if(T[i].l==T[i].r) return ; if(dis<=T[i*2].r) search(i*2,dis); else search(i*2+1,dis); } int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); int n,m; cin>>n>>m; _for(i,1,n+1) cin>>a[i]; build(1,1,n); while(m--){ int k; cin>>k; if(k==1){// int l,r,ad; cin>>l>>r>>ad; add( 1,l,r,ad ); } else { int pos; cin>>pos; res=0; search(1,pos); cout<<res<<endl; } } return 0; }