树链剖分模板

该博客提供了树链剖分的模板代码。代码包含了树链剖分的核心函数,如dfs1、dfs2,还实现了线段树的构建、更新和查询操作,以及最近公共祖先(LCA)的计算和区间更新功能,最后在主函数中进行输入处理和操作调用。
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<vector>
  4 #define tx top[x]
  5 #define ty top[y]
  6 #define ls o<<1
  7 #define rs o<<1|1
  8 #define M ((L+R)>>1)
  9 using namespace std;
 10 const int maxn = 100010;
 11 
 12 int n, m, P ,root, tot;
 13 int A[maxn], fa[maxn], deep[maxn], num[maxn], son[maxn], ID[maxn], top[maxn], fID[maxn];
 14 int sumv[maxn*4],addv[maxn*4];
 15 vector<int> G[maxn];
 16 
 17 void addedge(int x,int y) {
 18     G[x].push_back(y);
 19 }
 20 
 21 int dfs1(int x,int dep) { //返回包括自己,子树的大小 
 22     deep[x] = dep;
 23     int ret = 1;
 24     int len = G[x].size();
 25     int MX = 0;
 26     for(int i = 0;i < len;i++) {
 27         int tp = G[x][i];
 28         if(fa[x] == tp) continue;
 29         fa[tp] = x;
 30         int back = dfs1(tp,dep+1);
 31         if(back > MX) {
 32             son[x] = tp;
 33             MX = back;    
 34         } 
 35         ret += back;
 36     }
 37     num[x] = ret;
 38     return ret;
 39 }
 40 
 41 void dfs2(int x) {
 42     if(x == 0) return;
 43     ID[x] = ++tot;
 44     fID[tot] = x;
 45     if(son[fa[x]] == x) top[x] = top[fa[x]];
 46     else top[x] = x; 
 47     int len = G[x].size();
 48     dfs2(son[x]);
 49     for(int i = 0;i < len;i++) {
 50         int tp = G[x][i];
 51         if(tp != fa[x] && tp != son[x]) dfs2(tp);
 52     }
 53 }
 54 
 55 inline void build(int o,int L,int R) {
 56     if(L == R) {
 57         sumv[o] = A[fID[L]]%P;
 58         return;
 59     }
 60     build(ls,L,M);
 61     build(rs,M+1,R);
 62     sumv[o] = (sumv[ls] + sumv[rs])%P;
 63 }
 64 
 65 inline void pushdown(int o,int L,int R) {
 66     (addv[ls] += addv[o])%=P;
 67     (addv[rs] += addv[o])%=P;
 68     (sumv[ls] += addv[o]*(M-L+1))%=P;
 69     (sumv[rs] += addv[o]*(R-M))%=P;
 70     addv[o] = 0;
 71 }
 72 
 73 int ql,qr,qa;
 74 inline void update(int o,int L,int R) {
 75     if(ql <= L && R <= qr) {
 76         (addv[o] += qa)%=P;
 77         (sumv[o] += qa*(R-L+1))%=P;
 78         return;
 79     }
 80     pushdown(o,L,R);
 81     if(ql <= M) update(ls,L,M);
 82     if(qr > M) update(rs,M+1,R);
 83     sumv[o] = (sumv[ls] + sumv[rs])%P;
 84 }
 85 
 86 inline int query(int o,int L,int R) {
 87     if(ql <= L && R <= qr) return sumv[o]%P;
 88     int ret = 0;
 89     pushdown(o,L,R);
 90     if(ql <= M) (ret += query(ls,L,M))%=P;
 91     if(qr > M) (ret += query(rs,M+1,R))%=P;
 92     return ret%P; 
 93 }
 94 
 95 
 96 int LCA(int x,int y) {
 97     int ret = 0;
 98     while(tx != ty) {
 99         if(deep[tx] >= deep[ty]) {
100             //x 走到 top[x](编号小) 的 爸爸 ,top[x] 的爸爸是轻链 
101             ql = ID[tx], qr = ID[x];//下闭上开 
102             (ret += query(1,1,n))%=P; 
103             x = fa[tx];    
104         }
105         else {
106             ql = ID[ty], qr = ID[y];
107             (ret += query(1,1,n))%=P;
108             y = fa[ty];    
109         }
110     }
111 
112     if(x == y) {
113         ql = ID[x],qr = ql;
114         (ret += query(1,1,n))%=P;
115         return ret;
116     }
117      if(deep[x] > deep[y]) swap(x,y);
118     ql = ID[x], qr = ID[y]; 
119      (ret += query(1,1,n))%=P;
120   return ret;
121 }
122 
123 void LCA_add(int x,int y,int k) {
124     qa = k%P;
125     while(tx != ty) {
126         if(deep[tx] >= deep[ty]) {
127             //x 走到 top[x](编号小) 的 爸爸 ,top[x] 的爸爸是轻链 
128             ql = ID[tx], qr = ID[x];//下闭上开 
129             update(1,1,n); 
130             x = fa[tx];    
131         }
132         else {
133             ql = ID[ty], qr = ID[y];
134             update(1,1,n);
135             y = fa[ty];    
136         }
137     }
138 
139     if(x == y) {
140         ql = ID[x],qr = ql;
141         update(1,1,n);
142         return;
143     }
144      if(deep[x] > deep[y]) swap(x,y);
145     ql = ID[x], qr = ID[y]; 
146      update(1,1,n);
147 }
148 
149 int main() {
150     scanf("%d %d %d %d",&n, &m, &root, &P);
151     for(int i = 1;i <= n;i++) scanf("%d",A+i);
152     for(int i = 1,x,y;i < n;i++) {
153         scanf("%d%d",&x,&y);
154         addedge(x,y);
155         addedge(y,x);
156     }
157 
158     dfs1(root,1);
159     dfs2(root);
160     build(1,1,n);
161 
162     for(int i = 1,x,l,r,z;i <= m;i++) {
163         scanf("%d",&x);
164         if(x == 1) {
165             scanf("%d%d%d",&l,&r,&z);
166             LCA_add(l,r,z);
167         } else if(x == 2) {
168             scanf("%d%d",&l,&r);
169             printf("%d\n",LCA(l,r));
170         } else if(x == 3) {
171             scanf("%d%d",&l,&z);
172             ql = ID[l],qr = ql+num[l]-1,qa=z;
173             update(1,1,n);
174         } else {
175             scanf("%d",&z);
176             ql = ID[z],qr = ql + num[z]-1;
177             printf("%d\n",query(1,1,n));
178         }
179     }
180     return 0;
181 } 

 

转载于:https://www.cnblogs.com/frankscode/p/9533091.html

多角色体系 支持管理员、商家、消费者三种角色,权限分级管控: 管理员:负责平台整体配置、用户审核、数据监控等全局操作。 商家:管理店铺信息、发布商品、处理订单、回复评价等。 消费者:浏览商品、加入购物车、下单支付、评价商品等。 实现用户注册(手机号 / 邮箱验证)、登录(支持密码 / 验证码 / 第三方登录)、个人信息管理(头像、收货地址、密码修改)。 权限精细化控制 商家仅能管理自家店铺及商品,消费者仅能查看和购买商品,管理员拥有全平台数据访问权限。 二、商品管理功能 商品信息维护 商家可发布商品:填写名称、分类(如服饰、电子产品)、子类别(如手机、笔记本)、规格(尺寸、颜色、型号)、价格、库存、详情描述(图文)、物流信息(运费、发货地)等。 支持商品上下架、库存调整、信息编辑,系统自动记录商品状态变更日志。 商品分类与搜索 按多级分类展示商品(如 “数码产品→手机→智能手机”),支持自定义分类体系。 提供智能搜索功能:按关键词(名称、品牌)搜索,支持模糊匹配和搜索联想;结合用户浏览历史对搜索结果排序(优先展示高相关度商品)。 商品推荐 基于用户浏览、收藏、购买记录,推荐相似商品(如 “浏览过该商品的用户还买了…”)。 首页展示热门商品(销量 TOP10)、新品上架、限时折扣等推荐列表。 三、订单与交易管理 购物车与下单 消费者可将商品加入购物车,支持修改数量、选择规格、移除商品,系统自动计算总价(含运费、折扣)。 下单流程:确认收货地址→选择支付方式(在线支付、货到付款)→提交订单→系统生成唯一订单号。 订单处理流程 订单状态跟踪:待支付→已支付→商家发货→物流运输→消费者收货→订单完成,各状态变更实时通知用户。 商家端功能:查看新订单提醒、确认发货(填写物流单号)、处理退款申请(需审核理由)。 消费者端功能:查看订单详情、追踪物流、申请退款 / 退货、确认收货。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值