zoukankan      html  css  js  c++  java
  • 一个蒟蒻的板子们

    刷不动题,但是又要提高自己的代码能力,码码板子提高一下代码能力吧。开了键盘记录器,每天看看自己敲了多少次键盘吧。

    矩阵乘法与快速幂(LOJ #100)

    #include<cstdio>
    #include<vector>
    using namespace std;
    typedef vector<long long> vec;
    typedef vector<vec> matrix;
    typedef long long ll;
    const ll mod = 1e9 + 7;
    matrix mul(matrix &A,matrix &B) {
    	matrix C(A.size(),vec(B[0].size()));
    	for(int i = 0; i < int(A.size()); i++)
    		for(int k = 0; k < int(B.size()); k++)
    			for(int j = 0; j < int(B[0].size()); j++)
    				C[i][j] = (((C[i][j] + A[i][k] * B[k][j]) % mod) + mod) % mod;
    // 一定要先加模数再取模,否则爆负数就凉了,模数一定要放在最外层,防止爆 long long.
    	return C;
    }
    matrix pow(matrix A, ll n) {
        matrix B(A.size(), vec(A.size()));
        for(int i=0; i < int(A.size()); i++) B[i][i]=1;
        while(n) {
            if(n & 1) B = mul(B, A);
            A = mul(A, A);
            n >>= 1;
        }
        return B;
    }
    int n, p, m;
    int main() {
    	scanf("%d%d%d",&n, &p, &m);
    	matrix A(n, vec(p));
    	matrix B(p, vec(m));
    	for(int i = 0; i < n; ++i)
    		for(int j = 0; j < p; ++j)
    			scanf("%lld", &A[i][j]);
    	for(int i = 0; i < p; ++i)
    		for(int j = 0; j < m; ++j)
    			scanf("%lld", &B[i][j]);
    	matrix C = mul(A, B);
    	for(int i = 0; i < n; ++i) {
    		for(int j = 0; j < m; ++j)
    			printf("%lld ", C[i][j]);
    		puts("");
    	}
    	return 0;
    }
    

    树链剖分与线段树的区间加与查询(洛谷 P3384)

    #include <cstdio>
    #include <cctype>
    #include <vector>
    #include <algorithm>
    using namespace std;
    template<typename T> inline void read(T &x) {
    	x = 0; T w = 1; char ch = getchar();
    	while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();}
    	while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    	x *= w;
    }
    const int maxn = 100005;
    vector<int> G[maxn];
    typedef vector<int>::iterator Iter;
    int w[maxn], wt[maxn], son[maxn], id[maxn], fa[maxn], dep[maxn], siz[maxn],
    	top[maxn], cnt, n, m, r, mod, a, b, k, x, y, z;
    inline void add(int u, int v) {G[u].push_back(v);}
    struct node {
    	int l, r, mid, len, sum, laz; node *ls, *rs;
    } *root, MemPool[2 * maxn]; int MemCnt;
    inline void alloc(node* &x) {x = MemPool + MemCnt++;}
    inline void pushup(node *rt) {rt->sum = (rt->ls->sum + rt->rs->sum) % mod;}
    inline void pushdown(node *rt) {
    	rt->ls->laz += rt->laz, rt->rs->laz += rt->laz;
    	rt->ls->sum += rt->ls->len * rt->laz, rt->rs->sum += rt->rs->len * rt->laz;
    	rt->ls->sum %= mod, rt->rs->sum %= mod, rt->laz = 0;
    }
    inline void build(node* &rt, int l, int r) {
    	if(!rt) alloc(rt);
    	rt->l = l, rt->r = r, rt->mid = (l + r) >> 1, rt->len = r - l + 1;
    	if(l == r) {rt->sum = wt[l] % mod; return;}
    	build(rt->ls, rt->l, rt->mid), build(rt->rs, rt->mid + 1, rt->r);
    	pushup(rt);
    }
    inline int query(node *rt, int l, int r) {
    	if(rt->l >= l && rt->r <= r) return rt->sum % mod;
    	if(rt->laz) pushdown(rt);
    	int ans = 0;
    	if(l <= rt->mid) ans += query(rt->ls, l, r);
    	if(r > rt->mid) ans += query(rt->rs, l, r);
    	return ans % mod;
    }
    inline void update(node *rt, int l, int r, int k) {
    	if(rt->l >= l && rt->r <= r) {rt->laz += k, rt->sum += rt->len * k; return;}
    	if(rt->laz) pushdown(rt);
    	if(l <= rt->mid) update(rt->ls, l, r, k);
    	if(r > rt->mid) update(rt->rs, l, r, k);
    	pushup(rt);
    }
    inline int Range(int x, int y, int k = 0) {
    	int ans = 0;
    	while(top[x] != top[y]) {
    		if(dep[top[x]] < dep[top[y]]) swap(x, y);
    		if(k != 0) update(root, id[top[x]], id[x], k);
    		else ans = (ans + query(root, id[top[x]], id[x])) % mod; x = fa[top[x]];
    	}
    	if(dep[x] > dep[y]) swap(x, y);
    	if(k != 0) {update(root, id[x], id[y], k); return 0;}
    	return (ans + query(root, id[x], id[y])) % mod;
    }
    inline void dfs1(int x, int f, int deep) {
    	dep[x] = deep, fa[x] = f, siz[x] = 1;
    	for(Iter it = G[x].begin(); it != G[x].end(); ++it) {
    		if(*it == f) continue;
    		dfs1(*it, x, deep + 1);
    		siz[x] += siz[*it];
    		if(siz[*it] > siz[son[x]]) son[x] = *it;
    	}
    }
    inline void dfs2(int x, int topf) {
    	id[x] = ++cnt, wt[id[x]] = w[x], top[x] = topf;
    	if(!son[x]) return;
    	dfs2(son[x], topf);
    	for(Iter it = G[x].begin(); it != G[x].end(); ++it) {
    		if(*it == fa[x] || *it == son[x]) continue;
    		dfs2(*it, *it);
    	}
    }
    int main() {
    	read(n), read(m), read(r), read(mod);
    	for(int i = 1; i <= n; ++i) read(w[i]);
    	for(int i = 1; i < n; ++i) read(a), read(b), add(a, b), add(b, a);
    	dfs1(r, 0, 1), dfs2(r, r), build(root, 1, n);
    	while(m--) {
    		read(k), read(x);
    		if(k == 1) read(y), read(z), Range(x, y, z);
    		else if(k == 2) read(y), printf("%d
    ", Range(x, y));
    		else if(k == 3) read(y), update(root, id[x], id[x] + siz[x] - 1, y);
    		else printf("%d
    ", query(root, id[x], id[x] + siz[x] - 1));
    	}
    	return 0;
    }
    

    HLPP 最大流(cogs 14)

    #include <list>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    const int MAXN = 10005; const int INF = 2147483647;
    struct node {
    	int v, f, index;
    	node(int v, int f, int index) : v(v), f(f), index(index) {}
    };
    std::vector<node>edge[MAXN];
    std::vector<int>list[MAXN], height, count, que, excess;
    typedef std::list<int> List
    std::vector<List::iterator>iter;
    List dlist[MAXN];
    int highest, highestActive;
    typedef std::vector<node>::iterator Iterator;
    inline void addEdge(const int u, const int v, const int f) {
    	edge[u].push_back(node(v, f, edge[v].size()));
    	edge[v].push_back(node(u, 0, edge[u].size() - 1));
    }
    inline void globalRelabel(int n, int t) {
    	height.assign(n, n); height[t] = 0; count.assign(n, 0);
    	que.clear(); que.resize(n + 1); int qh = 0, qt = 0;
    	for(que[qt++] = t; qh < qt;) {
    		int u = que[qh++], h = height[u] + 1;
    		for(Iterator p = edge[u].begin(); p != edge[u].end(); ++p)
    			if(height[p->v] == n && edge[p->v][p->index].f > 0)
    				count[height[p->v] = h]++, que[qt++] = p->v;
    	}
    	for(int i = 0; i <= n; i++) list[i].clear(), dlist[i].clear();
    	for(int u = 0; u < n; ++u)
    		if(height[u] < n) {
    			iter[u] = dlist[height[u]].insert(dlist[height[u]].begin(), u);
    			if(excess[u] > 0) list[height[u]].push_back(u);
    		}
    	highest = (highestActive = height[que[qt - 1]]);
    }
    inline void push(int u, node &e) {
    	int v = e.v, df = std::min(excess[u], e.f);
    	e.f -= df; edge[v][e.index].f += df; excess[u] -= df; excess[v] += df;
    	if(0 < excess[v] && excess[v] <= df) list[height[v]].push_back(v);
    }
    inline void discharge(int n, int u) {
    	int nh = n;
    	for(Iterator p = edge[u].begin(); p != edge[u].end; ++p) {
    		if(p->f > 0) {
    			if(height[u] == height[p->v] + 1) {
    				push(u, *p);
    				if(!excess[u]) return;
    			} else nh = std::min(nh, height[p->v] + 1);
    		}
    	}
    	int h = height[u];
    	if(cound[h] == 1) {
    		for(int i =h; i <= highest; ++i) {
    			for(List::iterator p = dlist[i].begin(); p != dlist[i].end(); ++p)
    				--count[height[*p]], height[*p] = n;
    			dlist[i].clear();
    		}
    		highest = h - 1;
    	} else {
    		--count[h], iter[u] = dlist[h].erase(iter[u]), height[u] = nh;
    		if(nh == n) return;
    		++count[nh], iter[u] = dlist[nh].insert(dlist[nh].begin(), u);
    		highest = std::max(highest, highestActive = nh), list[nh].push_back(u);
    	}
    }
    inline int hlpp(int n, int s, int t) {
    	if(s == t) return 0;
    	highestActive = highest = 0;
    	height.assign(n, 0), height[s] = n, iter.resize(n);
    	for(int i = 0; i < n; ++i) if(i != s)
    		iter[i] = dlist[height[i]].insert(dlist[height[i]].begin(), i);
    	count.assign(n, 0), count[0] = n - 1;
    	excess.assign(n, 0), excess[s] = INF, excess[t] = -INF;
    	for(int i = 0; i < (int)edge[s].size(); ++i) push(s, edge[s][i]);
    	globalRelabel(n, t);
    	for(int u; heightActive >= 0;) {
    		if(list[highestActive].empty()) {--heightActive; continue;}
    		u = list[highestActive].back(), list[highestActive].pop_back();
    		discharge(n, u);
    	}
    	return excess[t] + INF;
    }
    

    弄了个水题做做,LICS 吧。最长上升公共子序列。所以怎么做?其实就 n^2 求一个 LIS,然后判断一下加入的数是否是公共的就行了。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n1, n2, T;
    int a[505], b[505], f[505], temp;
    int ans;
    int max(int a, int b) {return a < b ? b : a;}
    int main() {
    #ifndef LOCAL
    	freopen("codes.in", "r", stdin);
    	freopen("codes.out", "w", stdout);
    #endif
    	scanf("%d", &T);
    	while(T--) {
    		scanf("%d", &n1);
    		memset(a, 0, sizeof(a));
    		memset(b, 0, sizeof(b));
    		for(int i = 1; i <= n1; i++) scanf("%d", &a[i]);
    		scanf("%d", &n2);
    		for(int i = 1; i <= n2; i++) scanf("%d", &b[i]);
    		memset(f, 0, sizeof(f));
    		ans = 0;
    		for(int i = 1;i <= n1; i++) {
    			temp = 0;
    			for (int j = 1;j <= n2; j++) {
    				if (a[i] > b[j]) temp = max(temp, f[j]);
    				else if(a[i] == b[j]) f[j]=max(f[j], temp+1);
    				ans = max(ans, f[j]);
    			}
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    

    Splay 区间翻转(文艺平衡树)

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct node {
      node *ch[2]; int v, s, t;
      node (int v = 0) : v(v), s(1), t(0) {ch[0] = ch[1] = NULL;}
    } *root;
    inline int size(node *o) {return o ? o->s : 0;}
    inline void maintain(node *o) {o->s = 1 + size(o->ch[0]) + size(o->ch[1]);}
    inline void pushdown(node *o) {
      if(o->t) {
        swap(o->ch[0], o->ch[1]);
        if(o->ch[0]) o->ch[0]->t ^= 1;
        if(o->ch[1]) o->ch[1]->t ^= 1;
        o->t = 0;
      }
    }
    inline void rotate(node *&o, int t) {
      node *u = o->ch[t]; pushdown(u);
      o->ch[t] = u->ch[t ^ 1], u->ch[t ^ 1] = o; maintain(o), maintain(u), o = u;
    }
    inline void insert(node *&o, int v) {
      if(!o) o = new node(v);
      else insert(o->ch[v < o->v ? 0 : 1], v), maintain(o);
    }
    inline void splay(node *&o, int k) {
      pushdown(o);
      int l = size(o->ch[0]);
      if(l + 1 == k) return;
      int d = k <= l ? 0 : 1, k2 = d ? k - l - 1 : k;
      node *&c = o->ch[d]; pushdown(c);
      int l2 = size(c->ch[0]);
      if(l2 + 1 != k2) {
        int d2 = k2 <= l2 ? 0 : 1;
        splay(c->ch[d2], d2 ? k2 - l2 - 1 : k2);
        if(d == d2) rotate(o, d);
        else rotate(c, d2);
      }
      rotate(o, d);
    }
    int kth(node* &o, int k) {splay(o, k); return o->v;}
    int main() {
      int n, m;
      scanf("%d%d", &n, &m);
      for(int i = 1; i <= n; ++i) insert(root, i), splay(root, i);
      for(int i = 1; i <= m; ++i) {
        int l, r;
        scanf("%d%d", &l, &r);
        if(l == 1 && r == n) root->t ^= 1;
        else if(l == 1) splay(root, r + 1), root->ch[0]->t ^= 1;
        else if(r == n) splay(root, l - 1), root->ch[1]->t ^= 1;
        else splay(root, l - 1), splay(root->ch[1], r - size(root->ch[0])),
             root->ch[1]->ch[0]->t ^= 1;
      }
      for(int i = 1; i <= n; ++i) printf("%d%c", kth(root, i), i == n ? '
    ' : ' ');
      return 0;
    }
    
  • 相关阅读:
    POJ1470 Closest Common Ancestors(LCA入门)
    POJ1330 Nearest Common Ancestors(倍增LCA算法求无边权树的模板)
    HDU3078 Network (倍增LCA算法求树链)
    HDU2874 Connections between cities(并查集+倍增LCA算法求森林最短路)
    HDU2586 How far away?(倍增LCA算法求带边权树上最短路)
    POJ1062 昂贵的聘礼
    HDU4725 The Shortest Path in Nya Graph(堆优化的dijkstra算法)
    数据仓库详解:包括概念、架构及设计
    利用行为标签构建用户画像
    Spark SQL深度理解篇:模块实现、代码结构及执行流程总览(2)
  • 原文地址:https://www.cnblogs.com/TheRoadToAu/p/9544853.html
Copyright © 2011-2022 走看看