MangataのACM模板
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MangataのACM模板相关的知识,希望对你有一定的参考价值。
文章目录
本篇文章主要是Mangata平时写代码所用到的代码模板库,如有不对请在评论区指出
先放一个我的 常数优化的博客: 传送门
再放一个我的 代码格式博客: 传送门
数据结构
并查集
并查集是一种集合数据结构,通过并查集我们可以快速查询两个元素是否是一个集合,下面是Mangata常用的板子
/*
作者:Mangata
路径压缩并查集
*/
#include<cstdio>
const int N = 10005;//节点数
int fa[N],n;
void init(int len) //初始化,先让每个位置的父节点等于自身
for(int i=0; i<=n; ++i)
fa[i] = i;
int find(int x) //查找x的祖先节点
int t = x;//路径压缩
while(t != fa[t])
t = fa[t];
while(x != fa[x])
int temp = fa[x];
fa[x] = t;
x = temp;
return x;
void merge(int a,int b) //将x和y合并
a=find(a),b=find(b);
if(a != b)
fa[b] = a;
n--;
int main()
int t,m,a,b;
scanf("%d",&t);
while(t--)
scanf("%d%d",&n,&m);
init(n);
for(int i = 1; i <= m; ++i)
scanf("%d%d",&a,&b);
merge(a,b);
printf("%d\\n",n);//输出不同类别的总数目
return 0;
树状数组
二维单点修改,区间查询
例题:传送门
Code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 5e3;
ll tree[N][N<<2];
int n,m;
int lowbit(int x)
return -x & x;
inline void updata(int x,int y,int k)
while(x <= n)
int temp = y;
while(y <= m)
tree[x][y] += k;
y += lowbit(y);
x += lowbit(x);
y = temp;
inline ll get(int x,int y)
ll ans = 0;
while(x)
int temp = y;
while(y)
ans += tree[x][y];
y -= lowbit(y);
x -= lowbit(x);
y = temp;
return ans;
int main()
scanf("%d%d",&n,&m);
int a,b,c,d,op;
while(~scanf("%d",&op))
if(op == 1)
scanf("%d%d%d",&a,&b,&c);
updata(a,b,c);
else
scanf("%d%d%d%d",&a,&b,&c,&d);
printf("%lld\\n",get(c,d)-get(c,b-1)-get(a-1,d) + get(a-1,b-1));
return 0;
二维区间修改,单点查询
利用二维差分进行更新,更新和查询复杂度复杂度 l o g 2 2 log^2_2 log22
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 5e3+10;
ll tree[N][N];
ll t,n,m;
ll lowbit(ll x)
return -x & x;
void add(ll x,ll y,ll k) //单点更新
while(x <= n)
ll temp = y;
while(y <= m)
tree[x][y] += k;
y += lowbit(y);
x += lowbit(x);
y = temp;
void updata(ll x1,ll y1,ll x2,ll y2,ll k) //矩阵更新
add(x1,y1,k);
add(x1,y2 + 1,-k);
add(x2 + 1,y1,-k);
add(x2 + 1,y2 + 1,k);
ll query(ll x,ll y) //单点查询
ll ans = 0;
while(x)
ll temp = y;
while(y)
ans += tree[x][y];
y -= lowbit(y);
x -= lowbit(x);
y = temp;
return ans;
int main()
ll x1,x2,y1,y2,k;
memset(tree,0,sizeof tree);
scanf("%lld%lld",&n,&m);//n X m的矩阵
int op;
while(~scanf("%d",&op))
if(op == 1)
scanf("%lld%lld%lld%lld%lld",&x1,&y1,&x2,&y2,&k);
updata(x1,y1,x2,y2,k);
else
scanf("%lld%lld",&x1,&y1);
ll kk = query(x1,y1);
printf("%lld\\n",kk);
return 0;
二维区间修改,区间查询
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 3e3;
ll n,m;
ll tree[N][N][4];
ll read()
ll X=0; bool flag=1; char ch=getchar();
while(ch<'0'||ch>'9') if(ch=='-') flag=0; ch=getchar();
while(ch>='0'&&ch<='9') X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();
if(flag) return X;
return ~(X-1);
ll write(ll X)
if(X<0) putchar('-'); X=~(X-1);
int s[65],top=0;
while(X) s[++top]=X%10; X/=10;
if(!top) s[++top]=0;
while(top) putchar(s[top--]+'0');
inline ll lowbit(ll x)
return -x & x;
void add(ll x,ll y,ll k)
for(ll i = x;i <= n; i += lowbit(i))
for(ll j = y;j <= m; j += lowbit(j))
tree[i][j][0] += k;
tree[i][j][1] += k * x;
tree[i][j][2] += k * y;
tree[i][j][3] += k * x * y;
void updata(ll x1,ll y1,ll x2,ll y2,ll k)
add(x1,y1,k);
add(x1,y2 + 1,-k);
add(x2 + 1,y1,-k);
add(x2 + 1,y2 + 1,k);
ll ask(ll x,ll y)
ll ans = 0;
for(ll i = x;i; i -= lowbit(i))
for(ll j = y;j; j -= lowbit(j))
ans += (x + 1) * (y + 1) * tree[i][j][0]
- (y + 1) * tree[i][j][1]
- (x + 1) * tree[i][j][2]
+ tree[i][j][3];
return ans;
ll query(ll x1,ll y1,ll x2,ll y2)
return ask(x1-1,y1-1) - ask(x1 - 1,y2) - ask(x2,y1 - 1) + ask(x2,y2);
int main()
n = read();
m = read();
int op;
ll x1,x2,y1,y2,k;
while(~scanf("%d",&op))
if(op == 1)
scanf("%lld%lld%lld%lld%lld",&x1,&y1,&x2,&y2,&k);
updata(x1,y1,x2,y2,k);
else
scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2);
ll kk = query(x1,y1,x2,y2);
printf("%lld\\n",kk);
return 0;
线段树
单点修改,区间查询
例题:HDU1754
#include<bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 2000005;
int n,m;
int a[N],tree[N << 2];
void push_up(int k)
tree[k] = max(tree[k<<1],tree[k<<1|1]);
void build(int k, int l,int r)
if(l == r)
tree[k] = a[l];
else
int mid = l + ((r-l)>>1)计算几何
记TJPUのACM新生赛——Stay young, stay simple