各种各样的模板……

基础 语法

变换函数模板

#include<bits/stdc++.h>
using namespace std;

template <class T1,class T2>
T2 sum(T1 a,T1 b){
	return (T2)a+b;
}

int main(){
	cout<<sum<double,float>(1.11111111,2.22222222)<<endl;
	return 0;
}

快读模板

inline int read() {
	int n = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if(c == '-') f = (~ f + 1);
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		n = (n << 3) + (n << 1) + (c ^ 48);
		c = getchar();
	}
	return n * f;
}

邻接表模板

struct edge {
	int to, next, w;
}e[N << 1 | 1];

inline void add (int u, int v, ll w) {
	e[++ cnt].to = v;
	e[cnt].w = w;
	e[cnt].next = head[u];
	head[u] = cnt;
}

初级算法 初级数据结构

矩阵快速幂模板

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 110, MOD = 1e9 + 7;
int n, k;

struct matrix {
	ll s[N][N];
	matrix() {
		memset(s, 0, sizeof(s));
	}
	void build() {
		for (int i = 1; i <= n; ++ i)
			s[i][i] = 1;
	}
};

matrix operator *(const matrix &x, const matrix &y) {
	matrix z;
	for (int k = 1; k <= n; ++ k) {
		for (int i = 1; i <= n; ++ i) {
			for (int j = 1; j <= n; ++ j) {
				z.s[i][j] = (z.s[i][j] + x.s[i][k] * y.s[k][j] % MOD) % MOD;
			}
		}
	}
	return z;
}

int main() {
	cin >> n >> k;
	matrix a, ans;
	ans.build();
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= n; ++ j)
			cin >> a.s[i][j];
	do {
		if(k & 1) ans = ans * a;
		a = a * a; 
		k >>= 1;
	} while(k);
	for (int i = 1; i <= n; cout << endl, ++ i)
		for (int j = 1; j <= n; ++ j)
			cout << ans.s[i][j] << " ";
	return 0;
}

矩阵乘法模板

struct matrix {
	ll s[N][N];
	matrix() {
		memset(s, 0, sizeof(s));
	}
	void build() {
		for (int i = 1; i <= n; ++ i)
			s[i][i] = 1;
	}
};

matrix operator *(const matrix &x, const matrix &y) {
	matrix z;
	for (int k = 1; k <= n; ++ k) {
		for (int i = 1; i <= n; ++ i) {
			for (int j = 1; j <= n; ++ j) {
				z.s[i][j] = (z.s[i][j] + x.s[i][k] * y.s[k][j] % MOD) % MOD;
			}
		}
	}
	return z;
}

dijkstra最短路模板

/*
洛谷P3371
单向边,求从点s到各个点的最短路径 
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 10010;
const int M = 500010;

struct Edge {
    int u, v, w, next;
}e[M]; 
int n, m, s, cnt, head[N], vis[N], dis[N];
struct node
{
    int w,now;
    inline bool operator <(const node &x)const {
        return w > x.w;
    }
};
priority_queue<node>q; //重载运算符的优先队列(堆) 

void add_edge(int u, int v, int w) {
    e[++cnt].u = u;
    e[cnt].v = v;
    e[cnt].w = w;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void dijkstra()
{
    for(int i = 1; i <= n; i ++) dis[i] = INT_MAX;
    dis[s] = 0; //起点到起点距离为零 
    q.push((node){0, s});
    while(!q.empty()) { //当且仅当队列不为空 
        node x = q.top();
        q.pop();
        int u = x.now;
        if(vis[u]) continue; 
        vis[u] = 1;
        for(int i = head[u]; i; i = e[i].next) {
            int v = e[i].v;
            if(dis[v] > dis[u] + e[i].w) { //松弛操作 
                dis[v] = dis[u] + e[i].w;
                q.push((node){dis[v], v});
            }
        }
    }
    return ;
}

int main(){
    ios::sync_with_stdio(false);
    cin >> n >> m >> s;
    int x, y, z;
    for(int i = 1; i <= m; i ++) {
        cin >> x >> y >> z;
        add_edge(x, y, z);
    }
    dijkstra();
    for(int i = 1; i <= n; ++i)
        cout << dis[i] << " ";
    return 0;
}

SPFA最短路模板

#include <bits/stdc++.h>
using namespace std;
const int N = 110, M = 10010;

int n, m, dis[N], vis[N];
int tot, head[N], next[M], ver[M], edge[M];

void add(int u, int v, int w) {
    ver[++ tot] = v;
    edge[tot] = w;
    next[tot] = head[u];
    head[u] = tot;
}


void spfa() {
    memset(dis, 0x7fffffff, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    queue<int> q;
    q.push(1);
    dis[1] = 0;
    vis[1] = 1;
    while (q.size()) {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for (RI i = head[u]; i; i = Next[i]) {
            int v = ver[i], w = edge[i];
            if (dis[u] + w < dis[v]) {
                dis[v] = dis[u] + w;
                if (!vis[v]) {
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main() {
	ios::sync_with_stdio(false);
	return 0; 
}

背包问题模板

#include <bits/stdc++.h>
using namespace std;

const int A = 1e6 + 10;
int f[A], w[A], v[A];
/*---------0-1背包----------*/
int knapsack01(int n, int V) {
    memset(f, 0xc0c0c0c0, sizeof f); f[0] = 0; //需要装满
    memset(f, 0, sizeof f); //不需要装满 
    for (int i = 1; i <= n; i++)
        for (int j = V; j >= w[i]; j--)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
    return f[V];
}
/*-----------完全背包----------*/
int Fullbackpack(int n, int V) {
    for (int i = 1; i <= n; i++)
        for (int j = w[i]; j <= V; j++)
            f[j] = max(f[j], f[j - w[i]] + v[i]);
    return f[V];
}
/*-------多重背包二进制拆分-------*/
int number[A];
int MultiplePack1(int n, int V) {
    for (int i = 1; i <= n; i++) {
        int num = min(number[i], V / w[i]);
        for (int k = 1; num > 0; k <<= 1) {
            if (k > num) k = num;
            num -= k;
            for (int j = V; j >= w[i] * k; j--)
            f[j] = max(f[j], f[j - w[i] * k] + v[i] * k);
        }
    }
    return f[V];
}
int newv[A], neww[A], cnt;
int MultiplePack2(int n, int V) {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= c[i]; j <<= 1) {
            newv[cnt] = j * v[i];
            neww[cnt++] = j * w[i];
            c[i] -= j;
        }
        if (c[i] > 0) {
            newv[cnt] = c[i] * v[i];
            neww[cnt++] = c[i] * w[i];
        }
    }
    for (int i = 1; i <= cnt; i++)
	    for (int j = V; j >= neww[i]; j--)
	        f[j] = max(f[j], f[j - neww[i]] + newv[i]);
	return f[V];
}
/*------------多重背包单调队列优化------------*/
void MultiPack(int p, int w, int v) {
    for (int j = 0; j < cost; j++) {
        int head = 1,tail = 0;
        for (int k = j, i = 0; k <= V / 2; k += w, i++) {
            int r = f[k] - i * v;
            while (head <= tail and r >= q[tail].v) tail--;
            q[++tail] = node(i, r);
            while (q[head].id < i - num) head++;
            f[k] = q[head].v + i * v;
        }
    }
}
/*-----------二维费用背包----------*/
int t[A], g[A], dp[B][B];
int Costknapsack(int n, int V, int T) {
    for (int i = 1; i <= n; i++)
        for (int j = T; j >= w[i]; j--)
            for (int k = V; k >= g[i]; k--)
                dp[j][k] = max(dp[j][k], dp[j - w[i]][k - g[i]] + v[i]);
	return dp[T][V];
}
/*--------------分组背包--------------*/
int a[B][B];
int Groupingbackpack() {
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            scanf("%d", &a[i][j]);
    for (int i = 1; i <= n; i++)
        for (int j = m; j >= 0; j--)
            for (int k = 1; k <= j; k++)
                f[j] = max(f[j], f[j - k] + a[i][k]);
    return f[m];
}
/*------------K优解---------------*/
int kth(int n, int V, int k) {
	for (int i = 1; i <= n; i++) {
	    for (int j = V; j >= w[i]; j--) {
	  	    for (int l = 1; l <= k; l++) {
	  		    a[l] = f[j][l];
	  		    b[l] = f[j - w[i]][l] + v[i];
			}
			a[k + 1] = -1;
			b[k + 1] = -1;
			int x = 1, y = 1, o = 1;
			while (o != k + 1 and (a[x] != -1 or b[y] != -1)) {
				if (a[x] > b[y]) f[j][o] = a[x], x++;
				else f[j][o] = b[y], y++;
				if (f[j][o] != f[j][o - 1]) o++;
			}
		}
	}
	return f[V][k];
}
int main(int argc, char const *argv[]) {}

线段树模板

/*
演示线段树的一些基本操作
以区间和为例
支持区间查询,单点修改,区间修改等操作
至于单点查询……可以用区间查询代替嘛
附有测试代码(被注释了),可实时查看每次修改后的sum[]数组情况 
*/
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
int n, m, a[N];// a[]初始序列 
int sum[N << 2 | 1], add[N << 2 | 1]; // 存线段树的数组记得要开四倍空间 

inline int read() { // 快读 
	int x = 0, f = 1;
	char ch = getchar();
	while(!isdigit(ch)) {
		if(ch == '-') f = -f;
		ch = getchar();
	}
	while(isdigit(ch)) {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}

inline void build(int k, int l, int r) { // 建树 
	if(l == r) { // 叶子节点就可以直接存储 
		sum[k] = a[l];
		return ;
	}
	int mid = (l + r) >> 1;
	build(k << 1, l, mid);
	build(k << 1 | 1, mid + 1, r);
	sum[k] = sum[k << 1] + sum[k << 1 | 1]; // 记得维护一下 
	return ;
}

inline void Add(int k, int l, int r, int val) { // 给此区间打上懒标记 
	add[k] = val;
	sum[k] += val * (r - l + 1); // 区间和 
}

inline void pushdown(int k, int l, int r) { // 下传懒标记 
	if(!add[k]) return ;
	int mid = (l + r) >> 1;
	Add(k << 1, l, mid, add[k]);
	Add(k << 1 | 1, mid + 1, r, add[k]);
	add[k] = 0;
}

inline int query(int k, int l, int r, int x, int y) { // 区间查询
	if(x <= l && r <= y) {
		return sum[k];
	}
	int mid = (l + r) >> 1, res = 0;
	pushdown(k, l, r);
	if(x <= mid) res += query(k << 1, l, mid, x, y);
	if(y > mid) res += query(k << 1 | 1, mid + 1, r, x, y);
	return res;
}

inline void update(int k, int l, int r, int x, int y) { // 单点修改
	if(l == r) {
		sum[k] += y;
		return ;
	}
	int mid = (l + r) >> 1;
	if(x <= mid) update(k << 1, l, mid, x, y);
	else update(k << 1 | 1, mid + 1, r, x, y);
	sum[k] = sum[k << 1] + sum[k << 1 | 1]; // 记得维护一下
	return ;
} 

inline void modify(int k, int l, int r, int x, int y, int z) { // 区间修改
	if(x <= l && r <= y) { 
		Add(k, l, r, z);
		return ;
	} 
	int mid = (l + r) >> 1;
	pushdown(k, l, r);
	if(x <= mid) modify(k << 1, l, mid, x, y, z);
	if(y > mid) modify(k << 1 | 1, mid + 1, r, x, y, z);
	sum[k] = sum[k << 1] + sum[k << 1 | 1]; // 记得维护一下
	return ;
}

int main() {
	n = read(); m = read(); // n个点,m个操作 
	for (int i = 1; i <= n; ++ i)
		a[i] = read();
	build(1, 1, n);
	int x, y, z, opt; 
	for (int i = 1; i <= m; ++ i) {
		opt = read();
		if(opt == 1) { // 区间查询  [x,y]的区间和 
			x = read(); y = read();
			printf("%d\n", query(1, 1, n, x, y));
		} else if(opt == 2) { // 单点修改  x位置上数值加上y 
			x = read(); y = read();
			update(1, 1, n, x, y);
//			for (int i = 1; i <= 4 * n; ++ i)
//				cout << sum[i] << " ";
//			puts("");
		} else if(opt == 3) { // 区间修改  [x,y]区间每个数加上z 
			x = read(); y = read(); z = read();
			modify(1, 1, n, x, y, z);
//			for (int i = 1; i <= 4 * n; ++ i)
//				cout << sum[i] << " ";
//			puts("");
		} 
	}
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值