inlineintread(){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;}
#include<bits/stdc++.h>usingnamespace std;#define ll long longconstint N =110, MOD =1e9+7;int n, k;struct matrix {
ll s[N][N];matrix(){memset(s,0,sizeof(s));}voidbuild(){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;}intmain(){
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]<<" ";return0;}
矩阵乘法模板
struct matrix {
ll s[N][N];matrix(){memset(s,0,sizeof(s));}voidbuild(){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>usingnamespace std;constint N =10010;constint 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;inlinebooloperator<(const node &x)const{return w > x.w;}};
priority_queue<node>q;//重载运算符的优先队列(堆) voidadd_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;}voiddijkstra(){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;}intmain(){
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]<<" ";return0;}
SPFA最短路模板
#include<bits/stdc++.h>usingnamespace std;constint N =110, M =10010;int n, m, dis[N], vis[N];int tot, head[N], next[M], ver[M], edge[M];voidadd(int u,int v,int w){
ver[++ tot]= v;
edge[tot]= w;
next[tot]= head[u];
head[u]= tot;}voidspfa(){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);}}}}}intmain(){
ios::sync_with_stdio(false);return0;}
背包问题模板
#include<bits/stdc++.h>usingnamespace std;constint A =1e6+10;int f[A], w[A], v[A];/*---------0-1背包----------*/intknapsack01(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];}/*-----------完全背包----------*/intFullbackpack(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];intMultiplePack1(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;intMultiplePack2(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];}/*------------多重背包单调队列优化------------*/voidMultiPack(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];intCostknapsack(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];intGroupingbackpack(){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优解---------------*/intkth(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 +1and(a[x]!=-1or 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];}intmain(int argc,charconst*argv[]){}
线段树模板
/*
演示线段树的一些基本操作
以区间和为例
支持区间查询,单点修改,区间修改等操作
至于单点查询……可以用区间查询代替嘛
附有测试代码(被注释了),可实时查看每次修改后的sum[]数组情况
*/#include<bits/stdc++.h>usingnamespace std;constint N =1e6+10;int n, m, a[N];// a[]初始序列 int sum[N <<2|1], add[N <<2|1];// 存线段树的数组记得要开四倍空间 inlineintread(){// 快读 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;}inlinevoidbuild(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;}inlinevoidAdd(int k,int l,int r,int val){// 给此区间打上懒标记
add[k]= val;
sum[k]+= val *(r - l +1);// 区间和 }inlinevoidpushdown(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;}inlineintquery(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;}inlinevoidupdate(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);elseupdate(k <<1|1, mid +1, r, x, y);
sum[k]= sum[k <<1]+ sum[k <<1|1];// 记得维护一下return;}inlinevoidmodify(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;}intmain(){
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));}elseif(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("");}elseif(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("");}}return0;}