[CF]276E. Little Girl and Problem on Trees 树状数组

本文介绍了一种特殊树结构的处理方法,利用树的特性将其拆分为多个链,并使用BIT(二进制索引树)进行高效的操作,包括修改与查询节点值,解决了特定类型的树上操作问题。

题目大意是说给一棵特殊的树,除了1之外所有点的度数<=2,每个点存有一个值,初值都是0

之后给出两种树上操作:

0:将到某个点v的距离<=d的所有点权值加上x

1:输出某点v的权值


第一眼看错题了,以为是修改一条链上的所有点的值,发现是水题,开始BIT搞……之后发现看错题了,不是给两点链操作而是按距离,果断删代码……

又看了几眼,发现确实是BIT……很不爽地隔了很长时间才重新搞这题……


直接粘代码……

/*
  把1号节点去掉就是一堆链,dfs找链染色确定下标,在链上的整体操作可以用BIT c维护
  把所有点放到一起,处理出来每个颜色的区间,问题就解决了一半……
  另一半是跨越1的问题,这里值只和深度有关
  处理出来每个点的深度dep[],那么超过1的再用另一个BIT c1存起来
  每个点的值就是c.get(pos[v])+c1.get(dep[v]) ?
  其实还有一个问题……
  假设对vv进行了修改,跨越了1,c1的更新是针对所有链,相当于vv所在链重复计算了……
  所以要在修改点所在链开始,长度为d-dep[vv]的一段减去x
  剩下的就是堆代码
*/
#include <iostream>
#include <cstring>
using namespace std;
#define N 200005
#define _int long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
struct BIT {
  _int n,c[N+1]; void init(int s) {n=s; memset(c,0,sizeof(c));}
  void change(int p, _int k) {for (; p<=n; p+=p&-p) c[p]+=k;}
  _int sum(int p) {_int s=0; for (; p; p-=p&-p) s+=c[p]; return s;}
};
struct BIT_ex {
  BIT t; void init(int s) {t.init(s);}
  void change(int l, int r, _int k) {t.change(l,k); t.change(r+1,-k);}
  _int get(int p) {return t.sum(p);}
};


struct {int p,next;} e[N];
BIT_ex c,c1;
int g[N],col[N],p[N],dep[N],st[N],ed[N],tot=0,len=0,ans1=0;
void addedge(int a,int b) {e[++tot].p=b; e[tot].next=g[a]; g[a]=tot;}
void dfs(int now,int pre,int coo,int dee) {
  col[now]=coo; p[now]=++len; dep[now]=dee;
  if (dee==1) st[coo]=len; bool last=true;
  for (int tmp=g[now]; tmp; tmp=e[tmp].next)
    if (e[tmp].p!=pre) {last=false; dfs(e[tmp].p,now,coo,dee+1);}
  if (last) ed[coo]=len;
}
int main() {
  int n,q; cin >> n >> q;
  memset(g,0,sizeof(g));
  for (int i=1; i<n; i++) {
    int u,v; cin >> u >> v;
    addedge(u,v); addedge(v,u);
  }
  for (int tmp=g[1],coo=1; tmp; tmp=e[tmp].next) {
    dfs(e[tmp].p,1,coo,1); coo++;
  }
  c.init(len); c1.init(len);
  while (q--) {
    int t,v; cin >> t >> v;
    if (t) {
      if (v==1) cout << ans1 << endl;
      else cout << c.get(p[v])+c1.get(dep[v]) << endl;
    } else {
      int x,d; cin >> x >> d;
      if (v==1) {c1.change(1,d,x); ans1+=x;}
      else {
        c.change(max(p[v]-d,st[col[v]]),min(p[v]+d,ed[col[v]]),x);
        if (d>=dep[v]) {
          ans1+=x; 
          if (d>dep[v]) {
            c1.change(1,d-dep[v],x);
            c.change(st[col[v]],min(st[col[v]]+d-dep[v]-1,ed[col[v]]),-x);
          }
        }
      }
    }        
  }
  //system("pause");
  return 0;
}


p.s.其实这个实现并不好……如果把每个链当成不同的BIT限定好起点终点来做,应该还能提高效率,懒人路过……


(1)普通用户端(全平台) 音乐播放核心体验: 个性化首页:基于 “听歌历史 + 收藏偏好” 展示 “推荐歌单(每日 30 首)、新歌速递、相似曲风推荐”,支持按 “场景(通勤 / 学习 / 运动)” 切换推荐维度。 播放页功能:支持 “无损音质切换、倍速播放(0.5x-2.0x)、定时关闭、歌词逐句滚动”,提供 “沉浸式全屏模式”(隐藏冗余控件,突出歌词与专辑封面)。 多端同步:自动同步 “播放进度、收藏列表、歌单” 至所有登录设备(如手机暂停后,电脑端打开可继续播放)。 音乐发现与管理: 智能搜索:支持 “歌曲名 / 歌手 / 歌词片段” 搜索,提供 “模糊匹配(如输入‘晴天’联想‘周杰伦 - 晴天’)、热门搜索词推荐”,结果按 “热度 / 匹配度” 排序。 歌单管理:创建 “公开 / 私有 / 加密” 歌单,支持 “批量添加歌曲、拖拽排序、一键分享到社交平台”,系统自动生成 “歌单封面(基于歌曲风格配色)”。 音乐分类浏览:按 “曲风(流行 / 摇滚 / 古典)、语言(国语 / 英语 / 日语)、年代(80 后经典 / 2023 新歌)” 分层浏览,每个分类页展示 “TOP50 榜单”。 社交互动功能: 动态广场:查看 “关注的用户 / 音乐人发布的动态(如‘分享新歌感受’)、好友正在听的歌曲”,支持 “点赞 / 评论 / 转发”,可直接点击动态中的歌曲播放。 听歌排行:个人页展示 “本周听歌 TOP10、累计听歌时长”,平台定期生成 “全球 / 好友榜”(如 “好友中你本周听歌时长排名第 3”)。 音乐圈:加入 “特定曲风圈子(如‘古典音乐爱好者’)”,参与 “话题讨论(如‘你心中最经典的钢琴曲’)、线上歌单共创”。 (2)音乐人端(创作者中心) 作品管理: 音乐上传:支持 “无损音频(FLAC/WAV)+ 歌词文件(LRC)+ 专辑封面” 上传,填写 “歌曲信息
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值