ACM Code 1

ACM Code 1

1.SPFA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
using namespace std;
int n,m,s;
int e[900000],w[900000],head[900000],next[900000],k=0;
int q[3350000],d[900000];
bool v[900000];
int main()
{
int i,j;
memset(d,19,sizeof(d));
scanf("%d%d%d",&n,&m,&s);
for(i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
e[++k]=y;w[k]=z;next[k]=head[x];head[x]=k;
e[++k]=x;w[k]=z;next[k]=head[y];head[y]=k;
}
d[s]=0;
q[1]=s;
int f=1,r=1;
while(f<=r)
{
int x=q[f++];
k=head[x];
while(k!=0)
{
if(d[x]+w[k]<d[e[k]])
{
d[e[k]]=d[x]+w[k];
if(!v[e[k]])
{
q[++r]=e[k];
v[e[k]]=true;
}
}
k=next[k];
}
v[x]=0;
}
for(i=1;i<=n;i++) printf("%d ",d[i]);
return 0;
}

2.Dijkstra+Heap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <bits/stdc++.h>
using namespace std;
int n,m,s;
int e[1750000],w[1750000],head[950000],next[1750000];
int d[950000];
bool v[950000];
struct zxcv{int first, second;
};
bool operator < ( const zxcv &a, const zxcv &b)
{
return a.first>b.first;
}
priority_queue<zxcv> h;
void D()
{
while(h.empty()==0)
{
zxcv now=h.top();
h.pop();
int dii=now.first,x=now.second;
if(!v[x])
{
v[x]=1;
int k=head[x];
while(k)
{
if(w[k]+d[x]<d[e[k]])
{
d[e[k]]=d[x]+w[k];
if(!v[e[k]])
{
zxcv midd;
midd.first=d[e[k]];
midd.second=e[k];
h.push(midd);
}
}
k=next[k];
}
}
}
}
int main()
{
int i,j,k=0;
memset(d,40,sizeof(d));
scanf("%d%d%d",&n,&m,&s);
d[s]=0;
for(i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
e[++k]=y; w[k]=z; next[k]=head[x]; head[x]=k;
}
zxcv tmp;
tmp.first=0;
tmp.second=s;
h.push(tmp);
D();
for(i=1;i<=n;i++) printf("%d ",d[i]);
return 0;
}

3.树状数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include<bits/stdc++.h>
using namespace std;
int n,m,T;
int tri[607087];
int lowbit(int x)
{
return x&(-x);
}
void addedge(int x,int y)
{
while(x<=n)
{
tri[x]+=y;
x+=lowbit(x);
}
}
int S(int x)
{
int A=0;
while(x)
{
A+=tri[x];
x-=lowbit(x);
}
return A;
}
void work(int x,int y,bool h)
{
if(h) printf("%d\n",S(y)-S(x-1));
else addedge(x,y);
}
int main()
{
int i,j;
scanf("%d%d",&n,&T);
for(i=1;i<=n;i++)
{
int a=i,b;
scanf("%d",&b);
addedge(a,b);
}
while(T--)
{
int t,a,b;
scanf("%d%d%d",&t,&a,&b);
work(a,b,t-1);
}
return 0;
}

4.线段树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <bits/stdc++.h>
#define lc(x) x*2
#define rc(x) x*2+1
using namespace std;
int n,m,T;
long long tri[607087],lazy[607087];
void addedge(int x,int a,int b,int l,int r,int k)
{
int mid=(a+b)/2;
if(a==l&&b==r)
{
tri[x]+=(b-a)*k;
lazy[x]+=k;
return;
}
tri[lc(x)]+=(mid-a)*lazy[x];
lazy[lc(x)]+=lazy[x];
tri[rc(x)]+=(b-mid)*lazy[x];
lazy[rc(x)]+=lazy[x];
lazy[x]=0;
if(mid<=l)
addedge(rc(x),mid,b,l,r,k);
if(mid>=r)
addedge(lc(x),a,mid,l,r,k);
if(mid<r&&mid>l)
{
addedge(lc(x),a,mid,l,mid,k);
addedge(rc(x),mid,b,mid,r,k);
}
tri[x]=tri[lc(x)]+tri[rc(x)];
}
long long S(int x,int a,int b,int l,int r)
{
long long now,mid=(a+b)/2;
if(a==l&&b==r) return tri[x];
tri[lc(x)]+=(mid-a)*lazy[x];
lazy[lc(x)]+=lazy[x];
tri[rc(x)]+=(b-mid)*lazy[x];
lazy[rc(x)]+=lazy[x];
lazy[x]=0;
if(mid<=l)
now=S(rc(x),mid,b,l,r);
if(mid>=r)
now=S(lc(x),a,mid,l,r);
if(mid>l&&mid<r)
now=S(lc(x),a,mid,l,mid)+S(rc(x),mid,b,mid,r);
tri[x]=tri[lc(x)]+tri[rc(x)];
return now;
}
int main()
{
int i,j;
scanf("%d%d",&n,&T);
for(i=1;i<=n;i++)
{
int tmp;
scanf("%d",&tmp);
addedge(1,1,n+1,i,i+1,tmp);
}
while(T--)
{
int tipic;
scanf("%d",&tipic);
if(tipic==1)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
addedge(1,1,n+1,x,y+1,k);
}
if(tipic==2)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%lld\n",S(1,1,n+1,x,y+1));
}
}
return 0;
}

5.CRT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<bits/stdc++.h>
using namespace std;
long long n,a[5000],m[5000],S=0;
long long Pim=1,M[5000],t[5000];
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
else
{
long long R=exgcd(b,a%b,y,x);
y-=x*(a/b);
return R;
}
}
long long modinverse(long long x,long long y)
{
long long x0,y0;
exgcd(x,y,x0,y0);
long long A=(x0+750*y)%y;
return A;
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++) cin>>m[i]>>a[i];
for(i=1;i<=n;i++) Pim*=m[i];
for(i=1;i<=n;i++) M[i]=Pim/m[i];
for(i=1;i<=n;i++) t[i]=modinverse(M[i],m[i]);
for(i=1;i<=n;i++) S+=a[i]*t[i]*M[i];
cout<<S%Pim;
return 0;

}

6.ST 表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;
int n,m,pw[30]={1};
int f[3500000][30];
void find(int s,int t)
{
int p=s,q=t;
s=min(p,q),t=max(p,q);
int mid=log(t-s+1)/log(2);//对数换底公式
printf("%d\n",max(f[s][mid],f[t-pw[mid]+1][mid]));
}
int main()
{
int i,j,k,T;
for(i=1;i<=29;i++) pw[i]=pw[i-1]*2;
scanf("%d%d",&n,&T);
for(i=1;i<=n;i++) scanf("%d",&f[i][0]);
for(k=1;k<=log(n)/log(2)+1;k++)
{
i=1;
while(i+pw[k]<=n+1)
{
f[i][k]=max(f[i][k-1],f[i+pw[k-1]][k-1]);
//状态转移方程,非常重要
++i;
}
}
while(T--)
{
int L,R;
scanf("%d%d",&L,&R);
find(L,R);
}
return 0;
}

7.树——>链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <bits/stdc++.h>
using namespace std;
int n,m,r,p,cnt=0,A=0;
int e[423500],hd[423500],nxt[423500];
int tri[423500],lazy[423500];
int wold[423500],wnew[423500];
int f[423500],d[423500],sz[423500];
int hson[423500],rk[423500],top[423500],id[423500];
/*
名称 解释
f[u] 保存结点u的父亲节点
d[u] 保存结点u的深度值
sz[u] 保存以u为根的子树节点个数
hson[u] 保存重儿子
rk[u] 保存当前dfs标号在树中所对应的节点
top[u] 保存当前节点所在链的顶端节点
id[u] 保存树中每个节点剖分以后的新编号(DFS的执行顺序
函数临时变量均为对应大写首字母:F,D,S,H,R,T,I
*/
void buildtree(int x,int l,int r)
{
int mid=(l+r)/2;
if(l==r)
{
tri[x]=wnew[l]%p;
return ;
}
buildtree(2*x,l,mid);
buildtree(2*x+1,mid+1,r);
tri[x]=(tri[2*x]+tri[2*x+1])%p;
}
void pushdown(int x,int l,int r)
{
int mid=(l+r)/2;
if(lazy[x])
{
lazy[2*x]+=lazy[x];
lazy[2*x+1]+=lazy[x];
tri[2*x]+=(mid-l+1)*lazy[x];
tri[2*x+1]+=(r-mid)*lazy[x];
tri[2*x]%=p;
tri[2*x+1]%=p;
lazy[x]=0;
}
}
void update(int x,int l,int r,int a,int b,int k)
{
int mid=(l+r)/2;
if(a<=l&&r<=b)
{
lazy[x]+=k;
tri[x]+=k*(r-l+1);
}
else
{
pushdown(x,l,r);
if(a<=mid) update(2*x,l,mid,a,b,k);
if(b>mid) update(2*x+1,mid+1,r,a,b,k);
tri[x]=tri[x*2]+tri[x*2+1];
}
}
void visit(int x,int l,int r,int a,int b)
{
int mid=(l+r)/2;
if(a<=l&&r<=b)
{
A+=tri[x];
A%=p;
return;
}
pushdown(x,l,r);
if(a<=mid) visit(2*x,l,mid,a,b);
if(b>mid) visit(2*x+1,mid+1,r,a,b);
}
void dfs1(int x,int F,int D)
{
d[x]=D,f[x]=F,sz[x]=1;
int maxx=-1,k=hd[x];
while(k)
{
if(e[k]-F)
{
dfs1(e[k],x,D+1);
sz[x]+=sz[e[k]];
if(sz[e[k]]>maxx)
{
maxx=sz[wold[k]];
hson[x]=e[k];
}
}
k=nxt[k];
}
}
void dfs2(int x,int T)
{
top[x]=T,id[x]=++cnt,rk[cnt]=x;
wnew[cnt]=wold[x];
if(!hson[x]) return;
dfs2(hson[x],T);
int k=hd[x];
while(k)
{
if(e[k]-hson[x]&&e[k]-f[x]) dfs2(e[k],e[k]);
k=nxt[k];
}
}
void updrange(int x,int y,int k)
{
k%=p;
while(top[x]-top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
update(1,1,n,id[top[x]],id[x],k);
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);
update(1,1,n,id[x],id[y],k);
}
int qrange(int x,int y)
{
int rns=0;
while(top[x]-top[y])
{
if(d[top[x]]<d[top[y]]) swap(x,y);
A=0;
visit(1,1,n,id[top[x]],id[x]);
rns+=A,rns%=p;
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);
A=0;
visit(1,1,n,id[x],id[y]);
rns+=A;
return rns%p;
}
int qson(int x)
{
A=0;
visit(1,1,n,id[x],id[x]+sz[x]-1);
return A;
}
int updson(int x,int k)
{
update(1,1,n,id[x],id[x]+sz[x]-1,k);
}
int main()
{
int i,j,k=0;
scanf("%d%d%d%d",&n,&m,&r,&p);
for(i=1;i<=n;i++) scanf("%d",&wold[i]);
for(i=1;i<=n-1;i++)
{
int x,y;scanf("%d%d",&x,&y);
e[++k]=y,nxt[k]=hd[x],hd[x]=k;
e[++k]=x,nxt[k]=hd[y],hd[y]=k;
}
dfs1(r,0,1);
dfs2(r,r);
buildtree(1,1,n);
int tipic,x,y,z;
while(m--)
{
scanf("%d",&tipic);
switch(tipic)
{
case 1:
{
scanf("%d%d%d",&x,&y,&z);
updrange(x,y,z);
break;
}
case 2:
{
scanf("%d%d",&x,&y);
printf("%d\n",qrange(x,y));
break;
}
case 3:
{
scanf("%d%d",&x,&y);
updson(x,y);
break;
}
case 4:
{
scanf("%d",&x);
printf("%d\n",qson(x));
break;
}
default:break;
}
}
return 0;
}

8.基本二叉树操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <bits/stdc++.h>
using namespace std;
int n,m,ask;
struct asdf{int val,lson,rson,taim,size;}tri[2607087];
void addedge(int loc,int x)
{
if(!n)
{
n=1,tri[1].size=1,tri[1].val=x,tri[1].taim=1;
return;
}
tri[loc].size++;
if(tri[loc].val==x)
{
tri[loc].taim++;
return;
}
if(tri[loc].val>x)
{
if(tri[loc].lson) addedge(tri[loc].lson,x);
else
{
tri[++n].val=x;tri[n].taim=1;
tri[n].size=1;tri[loc].lson=n;
}
}
if(tri[loc].val<x)
{
if(tri[loc].rson)addedge(tri[loc].rson,x);
else
{
tri[++n].val=x;tri[n].taim=1;
tri[n].size=1;tri[loc].rson=n;
}
}
}
int findlow(int loc,int subget)
{
if(tri[loc].val>=ask)
{
if(!tri[loc].lson) return subget;
else return findlow(tri[loc].lson,subget);
}
else
{
if(!tri[loc].rson)
{
if(tri[loc].val<ask) return tri[loc].val;
else return subget;
}
if(tri[loc].taim) return findlow(tri[loc].rson,tri[loc].val);
else return findlow(tri[loc].rson,subget);
}
}
int findhigh(int loc,int subget)
{
if(tri[loc].val<=ask)
{
if(!tri[loc].rson) return subget;
else return findhigh(tri[loc].rson,subget);
}
else
{
if(!tri[loc].lson)
{
if(tri[loc].val>ask) return tri[loc].val;
else return subget;
}
if(tri[loc].size) return findhigh(tri[loc].lson,tri[loc].val);
else return findhigh(tri[loc].lson,subget);
}
}
int findrank(int loc)
{
if(!loc) return 0;
if(ask==tri[loc].val) return tri[tri[loc].lson].size;
if(ask>tri[loc].val) return findrank(tri[loc].rson)+tri[loc].taim+tri[tri[loc].lson].size;
if(ask<tri[loc].val) return findrank(tri[loc].lson);
}
int findnum(int loc)
{
if(!loc) return 2147483647;
if(tri[tri[loc].lson].size>=ask)return findnum(tri[loc].lson);
if(tri[tri[loc].lson].size+tri[loc].taim>=ask) return tri[loc].val;
ask-=tri[tri[loc].lson].size+tri[loc].taim;
return findnum(tri[loc].rson);
}
int main()
{
// freopen("1.hx902in","r",stdin);
int i,j,T;
scanf("%d",&T);
while(T--)
{
int tipic; scanf("%d",&tipic);
switch(tipic)
{
case 1://求x的排名
{
scanf("%d",&ask);printf("%d\n",1+findrank(1));
break;
}
case 2://求排名x的数
{
scanf("%d",&ask);printf("%d\n",findnum(1));
break;
}
case 3://求x的前驱
{
scanf("%d",&ask);printf("%d\n",findlow(1,-2147483647));
break;
}
case 4://求x的后继
{
scanf("%d",&ask);printf("%d\n",findhigh(1,+2147483647));
break;
}
case 5://插入x
{
scanf("%d",&ask); addedge(1,ask);
break;
}
default:break;
}
}
return 0;
}

9.Manacher

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <bits/stdc++.h>
using namespace std;
int n,m,A,f[45000000];
char c[45000000];
int Maxnum,Maxlen;
int main()
{
// freopen("testdata.in","r",stdin);
int i,j;
scanf("%s",c);
n=strlen(c)*2;
for(i=n;i>1;i--)
{
if(i%2) c[i]='*';
else c[i]=c[i/2-1];
}
c[0]='@',c[1]='*',c[n+1]='*',c[n+2]='~';
for(i=1;i<=n;i++)
{
if(Maxlen+Maxnum>i) f[i]=min(Maxlen+Maxnum-1,f[2*Maxnum-i]);
else f[i]=1;
while(c[i-f[i]]==c[i+f[i]]) ++f[i];
if(f[i]>Maxlen) Maxlen=f[i],Maxnum=i;
A=max(A,f[i]);
}
printf("%lld",A-1);
return 0;
}

10. 网络流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t,A;
int e[900000],w[900000],nxt[900000];
int hd[900000],dep[900000],q[3430000];
int bfs()
{
int f=1,r=1;
memset(dep,0,sizeof(dep));
dep[s]=1;q[1]=s;
while(f<=r)
{
int x=q[f++],k=hd[x];
while(k)
{
if((dep[e[k]]==0)&&(w[k]>0))
{
dep[e[k]]=dep[x]+1;
q[++r]=e[k];
}
k=nxt[k];
}
}
return dep[t];
}

int dfs(int x,int flow)
{
if(x==t) return flow;
int k=hd[x];
while(k)
{
if((w[k])&&(dep[e[k]]==dep[x]+1))
{
int dis=dfs(e[k],min(flow,w[k]));
if(dis>0)
{
w[k]-=dis;
if(k%2) w[k+1]+=dis;
else w[k-1]+=dis;
return dis;
}
}
k=nxt[k];
}
return 0;
}
void dinic()
{
int B=0;
while(bfs())
{
while(B=dfs(s,20011230)) A+=B;
}
}
int main ()
{
// freopen("flow1.in","r",stdin);
int k=0;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
e[++k]=y,w[k]=z,nxt[k]=hd[x],hd[x]=k;
e[++k]=x,w[k]==0,nxt[k]=hd[y],hd[y]=k;
}
dinic();
printf("%d\n",A);
return 0;
}

11.LCA

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// luogu-judger-enable-o2
#include <bits/stdc++.h>
using namespace std;
int n,m,s,h[1607087];
int e[1607087],hd[1607087],nxt[1607087];
int a[1607087],b[1607087],ans[1607087];
bool v[1607087];
int find(int x)
{
if(x-h[x]) return h[x]=find(h[x]);
else return x;
}
void lca(int x)
{
int i,now=hd[x];
v[x]=1;
while(now)
{
if(!v[e[now]])
{
lca(e[now]);
h[e[now]]=x;
}
now=nxt[now];
}
for(i=1;i<=m;i++)
{
if(a[i]==x&&v[b[i]]) ans[i]=find(b[i]);
if(b[i]==x&&v[a[i]]) ans[i]=find(a[i]);
}
}
int main()
{
int i,j,k=0;
scanf("%d%d%d",&n,&m,&s);
for(i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
e[++k]=y,nxt[k]=hd[x],hd[x]=k;
e[++k]=x,nxt[k]=hd[y],hd[y]=k;
}
memset(v,0,sizeof(v));
for(i=1;i<=n;i++) h[i]=i;
for(i=1;i<=m;i++) scanf("%d%d",&a[i],&b[i]);
lca(s);
for(i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}

ACM Code 1
http://example.com/2020/10/30/ACMCode1/
作者
huangx607087
发布于
2020年10月30日
许可协议