线段树
/************************************************ *Author : lrj124 *Created Time : 2018.11.05.16:31 *Mail : [email protected] *Problem : seg ************************************************/ #include <bits/stdc++.h> using namespace std; const int maxn = 100000 + 10; int n,m; struct seg { long long sum; int l,r,mark; }tree[maxn<<2]; inline void pushup(int root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; } inline void pushdown(int root) { if (tree[root].mark) { tree[root<<1].mark += tree[root].mark; tree[root<<1].sum += tree[root].mark*(tree[root<<1].r-tree[root<<1].l+1); tree[root<<1|1].mark += tree[root].mark; tree[root<<1|1].sum += tree[root].mark*(tree[root<<1|1].r-tree[root<<1|1].l+1); tree[root].mark = 0; } } inline void build(int l,int r,int root) { tree[root].l = l; tree[root].r = r; if (l == r) { scanf("%lld",&tree[root].sum); return; } int mid = l+r>>1; build(l,mid,root<<1); build(mid+1,r,root<<1|1); pushup(root); } inline void update(int l,int r,int ql,int qr,int root,long long x) { if (r < ql || l > qr) return; if (ql <= l && r <= qr) { tree[root].sum += x*(r-l+1); tree[root].mark += x; return; } pushdown(root); int mid = l+r>>1; update(l,mid,ql,qr,root<<1,x); update(mid+1,r,ql,qr,root<<1|1,x); pushup(root); } inline long long query(int l,int r,int ql,int qr,int root) { if (r < ql || l > qr) return 0; if (ql <= l && r <= qr) return tree[root].sum; pushdown(root); int mid = l+r>>1; return query(l,mid,ql,qr,root<<1)+query(mid+1,r,ql,qr,root<<1|1); } int main() { //freopen("seg.in","r",stdin); //freopen("seg.out","w",stdout); scanf("%d%d",&n,&m); build(1,n,1); while (m--) { int op,l,r; long long x; scanf("%d%d%d",&op,&l,&r); if (op == 1) { scanf("%lld",&x); update(1,n,l,r,1,x); } else printf("%lld\n",query(1,n,l,r,1)); } //cerr << 1.0*clock()/CLOCKS_PER_SEC << endl; return 0; }
树链剖分
/************************************************ *Author : lrj124 *Created Time : 2018.11.05.17:03 *Mail : [email protected] *Problem : tcd ************************************************/ #include <bits/stdc++.h> using namespace std; const int maxn = 100000 + 10; int cnt,n,m,rt,p,val[maxn],dep[maxn],father[maxn],top[maxn],size[maxn],son[maxn],Map[maxn],num[maxn]; vector<int> edge[maxn]; inline void dfs1(int now,int fa) { dep[now] = dep[fa]+1; father[now] = fa; size[now] = 1; for (size_t i = 0;i < edge[now].size();i++) if (edge[now][i] != fa) { dfs1(edge[now][i],now); size[now] += size[edge[now][i]]; if (size[edge[now][i]] > size[son[now]]) son[now] = edge[now][i]; } } inline void dfs2(int now,int ntop) { num[now] = ++cnt; Map[num[now]] = now; top[now] = ntop; if (son[now]) dfs2(son[now],ntop); for (size_t i = 0;i < edge[now].size();i++) if (edge[now][i] != father[now] && edge[now][i] != son[now]) dfs2(edge[now][i],edge[now][i]); } struct seg { long long sum,l,r,mark; } tree[maxn<<2]; inline void pushup(int root) { tree[root].sum = tree[root<<1].sum+tree[root<<1|1].sum; } inline void pushdown(int root) { if (tree[root].mark) { tree[root<<1].mark += tree[root].mark; tree[root<<1|1].mark += tree[root].mark; tree[root<<1].sum += tree[root].mark*(tree[root<<1].r-tree[root<<1].l+1); tree[root<<1|1].sum += tree[root].mark*(tree[root<<1|1].r-tree[root<<1|1].l+1); tree[root].mark = 0; } } inline void build(int l,int r,int root) { tree[root].l = l; tree[root].r = r; if (l == r) { tree[root].sum = val[Map[l]]; return; } int mid = l+r>>1; build(l,mid,root<<1); build(mid+1,r,root<<1|1); pushup(root); } inline void update(int l,int r,int ql,int qr,int root,int x) { if (r < ql || l > qr) return; if (ql <= l && r <= qr) { tree[root].sum += x*(r-l+1); tree[root].mark += x; return; } pushdown(root); int mid = l+r>>1; update(l,mid,ql,qr,root<<1,x); update(mid+1,r,ql,qr,root<<1|1,x); pushup(root); } inline long long query(int l,int r,int ql,int qr,int root) { if (r < ql || l > qr) return 0; if (ql <= l && r <= qr) return tree[root].sum; int mid = l+r>>1; pushdown(root); return query(l,mid,ql,qr,root<<1)+query(mid+1,r,ql,qr,root<<1|1); } inline void updateroad(int u,int v,long long x) { while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u,v); update(1,n,num[top[u]],num[u],1,x); u = father[top[u]]; } if (dep[u] > dep[v]) swap(u,v); update(1,n,num[u],num[v],1,x); } inline long long queryroad(int u,int v) { long long sum = 0; while (top[u] != top[v]) { if (dep[top[u]] < dep[top[v]]) swap(u,v); sum = (sum+query(1,n,num[top[u]],num[u],1))%p; u = father[top[u]]; } if (dep[u] > dep[v]) swap(u,v); return (sum+query(1,n,num[u],num[v],1))%p; } int main() { //freopen("tcd.in","r",stdin); //freopen("tcd.out","w",stdout); scanf("%d%d%d%d",&n,&m,&rt,&p); for (int i = 1;i <= n;i++) scanf("%d",&val[i]); for (int i = 1,u,v;i < n;i++) { scanf("%d%d",&u,&v); edge[u].push_back(v); edge[v].push_back(u); } dfs1(rt,0); dfs2(rt,rt); build(1,n,1); while (m--) { int op,u,v; long long w; scanf("%d%d",&op,&u); if (op == 1) { scanf("%d%lld",&v,&w); updateroad(u,v,w); } if (op == 2) { scanf("%d",&v); printf("%lld\n",queryroad(u,v)); } if (op == 3) { scanf("%lld",&w); update(1,n,num[u],num[u]+size[u]-1,1,w); } if (op == 4) printf("%lld\n",query(1,n,num[u],num[u]+size[u]-1,1)%p); } //cerr << 1.0*clock()/CLOCKS_PER_SEC << endl; return 0; }
Splay
......
LCT
......
Dinic
......
匈牙利
......
扩展欧几里德
......
Dijkstra
......
KMP
......
LCA
......
莫队
......