[SinGuLaRiTy] 复习模板-数据结构
Posted SinGuLaRiTy2001
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SinGuLaRiTy] 复习模板-数据结构相关的知识,希望对你有一定的参考价值。
【SinGuLaRiTy-1040】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.
二维线段树 2D_Segment_Tree
//示例:单点修改,区间求和。 //注意内存限制 #include<cstdio> #include<iostream> #include<cstring> const int MAXN = 1025; #define L(x) ((x)<<1) #define R(x) ((x)<<1|1) #define M(x,y) (((x)+(y))>>1) using namespace std; int N, ans; struct Node { short l, r; int sum; } a[MAXN*4][MAXN*4]; int refer[MAXN]; void build_y(int &xid, int i, short l, short r) { a[xid][i].l = l; a[xid][i].r = r; if (l == r) return; build_y(xid, L(i), l, M(l,r)); build_y(xid, R(i), M(l,r)+1, r); } void build_x(int i, short l, short r) { a[0][i].l = l; a[0][i].r = r; build_y(i, 1, 0, N); if (l==r) { refer[l]=i; return; } build_x(L(i), l, M(l,r)); build_x(R(i), M(l,r)+1, r); } void update(int x, int y, int &dt) { int i = refer[x], j; while (i>0) { j = refer[y]; while (j>0) a[i][j].sum += dt, j >>= 1; i >>= 1; } } void sum_y(int& xid, int i, int& y1, int& y2) { if (a[xid][i].l > y2 || a[xid][i].r < y1) return; if (a[xid][i].l >= y1 && a[xid][i].r <= y2) { ans += a[xid][i].sum; return; } sum_y(xid, L(i), y1, y2); sum_y(xid, R(i), y1, y2); } void sum_x(int i, int& x1, int& y1, int& x2, int& y2) { if (a[0][i].l > x2 || a[0][i].r < x1) return; if (a[0][i].l >= x1 && a[0][i].r <= x2) { sum_y(i, 1, y1, y2); return; } sum_x(L(i), x1, y1, x2, y2); sum_x(R(i), x1, y1, x2, y2); } int main() { int op, x1, y1, x2, y2, t; scanf("%d%d", &N, &N); build_x(1, 0, N); while (scanf("%d", &op) && op!=3) { if (op == 1) { scanf("%d%d%d", &x1, &y1, &t); update(x1, y1, t); } else { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); ans = 0; sum_x(1, x1, y1, x2, y2); printf("%d\n", ans); } } return 0; }
双向队列 deque
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 100010; struct Deque { int nxt[MAXN], prv[MAXN], stk[MAXN], tp; int val[MAXN]; int f, b, size, t; void clear() { f=b=size=0; tp=MAXN-2; for (int i=1; i<MAXN; ++i) nxt[i] = prv[i] = 0, stk[i] = i; } Deque() { clear(); } void push(bool d, int v) { if (!size) { f = b = stk[tp--]; val[f] = v; prv[f]=nxt[f]=0; } else { t = stk[tp--]; if (d) { nxt[b] = t; prv[t] = b; nxt[t] = 0; val[t] = v; b = t;} else { nxt[t] = f; prv[f] = t; prv[t] = 0; val[t] = v; f = t; } } ++size; } void pop(bool d) { --size; if (d) stk[++tp] = b, b = prv[b]; else stk[++tp] = f, f = nxt[f]; } int front() { return val[f]; } int back() { return val[b]; } } q; int main() { return 0; }
Splay平衡树 Splay_Tree
#include<iostream> #include<cstdio> #include<cstring> #define Max(a,b) ((a)>(b)?(a):(b)) #define L(x) x->ch[0] #define R(x) x->ch[1] using namespace std; const int MAXN = 100010; struct Node { int sz; Node *fa, *ch[2]; Node () { sz=0; } }nil, *NIL=&nil; struct SeqSplay //用来维护区间操作的splay { Node a[MAXN], *root; void init() { root=NIL; } inline void pushup(Node *x) { x->sz = L(x)->sz + R(x)->sz + 1;//size域一定要维护 } inline void pushdown(Node *x) { //标记下放或者左右交换 } void rotate(Node *x, int d) // 0左1右 { Node *y = x->fa; if (y==root) root = x; pushdown(y); pushdown(x); y->ch[!d] = x->ch[d]; if (x->ch[d] != NIL) x->ch[d]->fa = y; x->fa = y->fa; if (y->fa != NIL) y->fa->ch[ y->fa->ch[1]==y ] = x; x->ch[d] = y; y->fa = x; pushup(y); pushup(x); } void splay(Node*x, Node*target)//双旋至target以下 { Node *y, *z; while (x->fa != target) { y = x->fa; z = y->fa; pushdown(x); if (z == target) { rotate(x, x==y->ch[0]); return; } if (y == L(z)) if (x == L(y)) rotate(y, 1), rotate(x, 1); else rotate(x, 0), rotate(x, 1); else if (x == R(y)) rotate(y, 0), rotate(x, 0); else rotate(x, 1), rotate(x, 0); pushup(x); } } Node* build(int l, int r, Node* fa) { if (l>r) return NIL; int mid = (l+r)>>1; a[mid].ch[0] = build(l, mid-1, &a[mid]); a[mid].ch[1] = build(mid+1, r, &a[mid]); //此处根据题意具体录入节点内容 pushup(&a[mid]); return &a[mid]; } void init(int l, int r) { //伸展树的初始化,外部调用时一定要空置左右端点 root = build(l, r, NIL); } void getkth(int k, Node *&target)//将第k个元素旋转至target下面 { Node *t = root; while (1) { pushdown(t); if (k == (t->ch[0]->sz)+1) { splay(t, target); return; } if (k <= L(t)->sz) t = L(t); else k-=L(t)->sz+1, t = R(t); } } void form(int l, int r) //将区间[l,r]旋转至操作区域 { getkth(l, root); getkth(r+2, R(root)); } } tree; int main() { return 0; }
线段树
struct node { int l ,r ,sum ; }tre[MAXN<<2] ; void build(int code,int l,int r) { tre[code].l=l ,tre[code].r=r ; if(l==r)return; build(code*2,l,(l+r)/2); build(code*2+1,(l+r)/2+1,r); } void update(int code,int l,int r) { if(l<=tre[code].l&&tre[code].r<=r) { //修改 return; } //若有懒标记 pushdown(); int mid=(tre[code].l+tre[code].r)/2; if(l<=mid)update(code*2,l,r); if(mid<r)update(code*2+1,l,r); //更新 pushup(); tre[code].sum=tre[code*2].sum+tre[code*2+1].sum; } int query(int code,int l,int r) { if(l<=tre[code].l&&tre[code].r<=r) return tre[code].sum; int mid=(tre[code].l+tre[code].r)/2 ,ans=0 ; //pushdown(); if(l<=mid)ans+=query(code*2,l,r); if(mid<r)ans+=query(code*2+1,l,r); return ans; }
二维树状数组
#define LL long long int #define lowbit(a) ((a)&(-(a))) LL tre[MAXN+5][MAXN+5] ; void update(int a,int b,LL val) { val%=mod; for(;a<=n;a+=lowbit(a)) for(int j=y;j<=m;j+=lowbit(j)) { tre[i][j]+=val; if(tre[a][j]>=mod)tre[a][j]-=mod; } } LL getsum(int x,int y) { LL ans=0; for(;x>0;x-=lowbit(x)) for(int j=y;j>0;j-=lowbit(j)) { ans+=tre[x][j]; if(ans>=mod)ans-=mod; } return ans; }
树状数组
#define lowbit(a) ((a)&(-(a))) #define LL long long int LL tre[MAXN+5] ; void update(LL a,int pos) { a%=mod; while(pos<=n) { tre[pos]+=a; if(tre[pos]>=mod)tre[pos]-=mod; pos+=lowbit(pos); } } LL getsum(int pos) { LL ans=0 ; while(pos>0) { ans+=tre[pos]; if(ans>=mod)ans-=mod; pos-=lowbit(pos); } return ans; }
并查集
int getroot(int a) { if(fa[a]==a)return a; return fa[a]=getroot(fa[a]); } void Union(int a,int b) { fa[getroot(a)]=getroot(b); }
以上是关于[SinGuLaRiTy] 复习模板-数据结构的主要内容,如果未能解决你的问题,请参考以下文章