一个蒟蒻的板子们

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

矩阵乘法与快速幂(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\n", Range(x, y));
		else if(k == 3) read(y), update(root, id[x], id[x] + siz[x] - 1, y);
		else printf("%d\n", 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\n", 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 ? '\n' : ' ');
  return 0;
}
posted @ 2018-08-27 21:25  baka  阅读(190)  评论(0编辑  收藏  举报