[总结]板子整理QAQ

放些我比较喜欢的板子QAQ

SPFA最短路:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int N=2500+5;
 9 const int M=6200+5;
10 int n,m;
11 struct edge{
12     int from,to,dis;
13 }e[M<<1];
14 int head[N],nxt[M<<1],tot=0;
15 void adde(int f,int t,int d)
16 {
17     e[++tot]=(edge){f,t,d};
18     nxt[tot]=head[f];
19     head[f]=tot;
20 }
21 int dist[N];
22 bool inq[N];
23 queue<int> q;
24 void spfa(int st)
25 {
26     dist[st]=0;
27     q.push(st);
28     inq[st]=1;
29     while(!q.empty())
30     {
31         int u=q.front();
32         q.pop();
33         inq[u]=0;
34         for(int i=head[u];i;i=nxt[i])
35         {
36             int v=e[i].to;
37             if(dist[v]>dist[u]+e[i].dis)
38             {
39                 dist[v]=dist[u]+e[i].dis;
40                 if(!inq[v])
41                 {
42                     q.push(v);
43                     inq[v]=1;
44                 }
45             }
46         }
47     }
48 }
49 int main()
50 {
51     memset(dist,0x3f,sizeof(dist));
52     int st,ed;
53     scanf("%d%d%d%d",&n,&m,&st,&ed);
54     int a,b,c;
55     for(int i=1;i<=m;i++)
56     {
57         scanf("%d%d%d",&a,&b,&c);
58         adde(a,b,c);
59         adde(b,a,c);
60     }
61     spfa(st);
62     printf("%d\n",dist[ed]);
63     return 0;
64 }

Dijkstra 最短路+堆优化

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int N=2500+5;
 9 const int M=6200+5;
10 int n,m;
11 struct edge{
12     int from,to,dis;
13 }e[M<<1];
14 int head[N],nxt[M<<1],tot=0;
15 void adde(int f,int t,int d)
16 {
17     e[++tot]=(edge){f,t,d};
18     nxt[tot]=head[f];
19     head[f]=tot;
20 }
21 int dist[N];
22 bool vis[N];
23 struct zt{
24     int id,dis;
25     bool operator <(const zt X) const{
26         return X.dis<dis;
27     }
28 };
29 priority_queue<zt> q;
30 void dij(int st)
31 {
32     dist[st]=0;
33     q.push((zt){st,0});
34     while(!q.empty())
35     {
36         int u=q.top().id;
37         q.pop();
38         if(vis[u]) continue;
39         vis[u]=1;
40         for(int i=head[u];i;i=nxt[i])
41         {
42             int v=e[i].to;
43             if(dist[v]>dist[u]+e[i].dis)
44             {
45                 dist[v]=dist[u]+e[i].dis;
46                 q.push((zt){v,dist[v]});
47             }
48         }
49     }
50 }
51 int main()
52 {
53     memset(dist,0x3f,sizeof(dist));
54     int st,ed;
55     scanf("%d%d%d%d",&n,&m,&st,&ed);
56     int a,b,c;
57     for(int i=1;i<=m;i++)
58     {
59         scanf("%d%d%d",&a,&b,&c);
60         adde(a,b,c);
61         adde(b,a,c);
62     }
63     dij(st);
64     printf("%d\n",dist[ed]);
65     return 0;
66 }

倍增版LCA,用于处理树上任意两点的距离

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int N=5e4+5;
 9 int n,m;
10 struct edge{
11     int from,to,dis;
12 }e[N<<1];
13 int head[N],nxt[N<<1],tot=0;
14 void adde(int f,int t,int d)
15 {
16     e[++tot]=(edge){f,t,d};
17     nxt[tot]=head[f];
18     head[f]=tot;
19 }
20 int deep[N],anc[N][25],rank[N];
21 void dfs(int t,int f)
22 {
23     deep[t]=deep[f]+1;
24     anc[t][0]=f;
25     for(int i=head[t];i;i=nxt[i])
26     {
27         int v=e[i].to;
28         if(v!=f)
29         {
30             rank[v]=rank[t]+e[i].dis;
31             dfs(v,t);
32         }
33     }
34 }
35 void make_lca()
36 {
37     for(int j=1;j<=23;j++)
38         for(int i=1;i<=n;i++)
39             anc[i][j]=anc[anc[i][j-1]][j-1];
40 }
41 int lca(int x,int y)
42 {
43     if(deep[x]<deep[y]) swap(x,y);
44     int dd=deep[x]-deep[y];
45     for(int i=0;(1<<i)<=dd;i++)
46     {
47         if((1<<i)&dd) x=anc[x][i];
48     }
49     if(x==y) return x;
50     for(int i=23;i>=0;i--)
51     {
52         if(anc[x][i]!=anc[y][i])
53             x=anc[x][i],y=anc[y][i];
54     }
55     return anc[x][0];
56 }
57 
58 int main()
59 {
60     scanf("%d",&n);
61     int a,b,c;
62     for(int i=1;i<=n-1;i++)
63     {
64         scanf("%d%d%d",&a,&b,&c);
65         a++,b++;
66         adde(a,b,c);
67         adde(b,a,c);
68     }
69     dfs(1,0);
70     make_lca();
71     scanf("%d",&m);
72     while(m--)
73     {
74         scanf("%d%d",&a,&b);
75         a++,b++;
76         printf("%d\n",rank[a]+rank[b]-2*rank[lca(a,b)]);
77     }
78     return 0;
79 }

树剖版LCA,据说比倍增快

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int N=5e4+5;
 9 int n,m;
10 struct edge{
11     int from,to,dis;
12 }e[N<<1];
13 int head[N],nxt[N<<1],tot=0;
14 void adde(int f,int t,int d)
15 {
16     e[++tot]=(edge){f,t,d};
17     nxt[tot]=head[f];
18     head[f]=tot;
19 }
20 int deep[N],fa[N],siz[N],hson[N],top[N],rank[N];
21 void dfs1(int t,int f)
22 {
23     deep[t]=deep[f]+1;
24     fa[t]=f;
25     for(int i=head[t];i;i=nxt[i])
26     {
27         int v=e[i].to;
28         if(v!=f)
29         {
30             rank[v]=rank[t]+e[i].dis;
31             dfs1(v,t);
32             siz[t]+=siz[v];
33             if(!hson[t]||siz[v]>siz[hson[t]]) hson[t]=v;
34         }
35     }
36 }
37 void dfs2(int t,int tp)
38 {
39     top[t]=tp;
40     if(!hson[t]) return;
41     dfs2(hson[t],tp);
42     for(int i=head[t];i;i=nxt[i])
43     {
44         int v=e[i].to;
45         if(v!=fa[t]&&v!=hson[t]) dfs2(v,v);
46     }
47 }
48 int lca(int x,int y)
49 {
50     int fx=top[x],fy=top[y];
51     while(fx!=fy)
52     {
53         if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy);
54         x=fa[fx],fx=top[x];
55     }
56     return deep[x]<deep[y]?x:y;
57 }
58 int main()
59 {
60     scanf("%d",&n);
61     int a,b,c;
62     for(int i=1;i<=n-1;i++)
63     {
64         scanf("%d%d%d",&a,&b,&c);
65         a++,b++;
66         adde(a,b,c);
67         adde(b,a,c);
68     }
69     scanf("%d",&m);
70     dfs1(1,0);
71     dfs2(1,1);
72     while(m--)
73     {
74         scanf("%d%d",&a,&b);
75         a++,b++;
76         printf("%d\n",rank[a]+rank[b]-2*rank[lca(a,b)]);
77     }
78     return 0;
79 }

线段树,用于区间搞事

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=2e5+5;
 9 typedef long long ll;
10 int n,m;
11 ll num[maxn];
12 struct seg{
13     int l,r;
14     ll sum,add;
15 }tree[maxn<<2];
16 inline void update(int p)
17 {
18     tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
19 }
20 void build(int p,int l,int r)
21 {
22     tree[p].l=l;
23     tree[p].r=r;
24     if(l==r)
25     {
26         tree[p].sum=num[l];
27         return;
28     }
29     int mid=l+r>>1;
30     build(p<<1,l,mid);
31     build(p<<1|1,mid+1,r);
32     update(p);
33 }
34 void pushdown(int p)
35 {
36     if(tree[p].add)
37     {
38         ll v=tree[p].add;
39         int lz=p<<1,rz=p<<1|1;
40         tree[lz].add+=v;
41         tree[lz].sum+=v*(tree[lz].r-tree[lz].l+1);
42         tree[rz].add+=v;
43         tree[rz].sum+=v*(tree[rz].r-tree[rz].l+1);
44         tree[p].add=0;
45     }
46 }
47 void change(int p,int l,int r,ll v)
48 {
49     if(l<=tree[p].l&&r>=tree[p].r)
50     {
51         tree[p].add+=v;
52         tree[p].sum+=v*(tree[p].r-tree[p].l+1);
53         return;
54     }
55     pushdown(p);
56     int mid=tree[p].l+tree[p].r>>1;
57     if(l<=mid) change(p<<1,l,r,v);
58     if(r>mid) change(p<<1|1,l,r,v);
59     update(p);
60 }
61 ll ask_sum(int p,int l,int r)
62 {
63     if(l<=tree[p].l&&r>=tree[p].r)
64     {
65         return tree[p].sum;
66     }
67     pushdown(p);
68     int mid=tree[p].l+tree[p].r>>1;
69     ll ret=0;
70     if(l<=mid) ret+=ask_sum(p<<1,l,r);
71     if(r>mid) ret+=ask_sum(p<<1|1,l,r);
72     return ret;
73 }
74 int main()
75 {
76     scanf("%d",&n);
77     for(int i=1;i<=n;i++)
78     {
79         scanf("%lld",&num[i]);
80     }
81     build(1,1,n);
82     int op,a,b;
83     ll c;
84     scanf("%d",&m);
85     while(m--)
86     {
87         scanf("%d%d%d",&op,&a,&b);
88         if(op==1)
89         {
90             scanf("%lld",&c);
91             change(1,a,b,c);
92         }
93         else if(op==2)
94         {
95             printf("%lld\n",ask_sum(1,a,b));
96         }
97     }
98     return 0;
99 }

树状数组,区间求和比较方便,代码简短

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=1e5+5;
 9 #define lowbit(x) x&-x
10 int n,m;
11 int tree[maxn];
12 void change(int pos,int v)
13 {
14     while(pos<=n)
15     {
16         tree[pos]+=v;
17         pos+=lowbit(pos);
18     }
19 }
20 int ask_sum(int l,int r)
21 {
22     if(l==1)
23     {
24         int ret=0;
25         while(r)
26         {
27             ret+=tree[r];
28             r-=lowbit(r);
29         }
30         return ret;
31     }
32     return ask_sum(1,r)-ask_sum(1,l-1);
33 }
34 int main()
35 {
36     scanf("%d",&n);
37     int x;
38     for(int i=1;i<=n;i++)
39     {
40         scanf("%d",&x);
41         change(i,x);
42     }
43     scanf("%d",&m);
44     int op,a,b;
45     while(m--)
46     {
47         scanf("%d%d%d",&op,&a,&b);
48         if(op==1) change(a,b);
49         else if(op==2) printf("%d\n",ask_sum(a,b));
50     }
51     return 0;
52 }

分块,和线段树、树状数组是一家子QAQ,代码优美,逼格较高

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 using namespace std;
 8 const int maxn=2e5+5;
 9 const int sq=460+5;
10 typedef long long ll;
11 int n,m;
12 ll num[maxn];
13 ll ksum[sq],kadd[sq];
14 int inbl[maxn],kl;
15 void change(int l,int r,ll v)
16 {
17     if(inbl[l]==inbl[r])
18     {
19         for(int i=l;i<=r;i++) num[i]+=v,ksum[inbl[i]]+=v;
20         return;
21     }
22     for(int i=l;inbl[i]==inbl[l];i++) num[i]+=v,ksum[inbl[i]]+=v;
23     for(int i=r;inbl[i]==inbl[r];i--) num[i]+=v,ksum[inbl[i]]+=v;
24     for(int i=inbl[l]+1;i<inbl[r];i++) kadd[i]+=v;
25 }
26 ll ask_sum(int l,int r)
27 {
28     ll ret=0;
29     if(inbl[l]==inbl[r])
30     {
31         for(int i=l;i<=r;i++) ret+=num[i]+kadd[inbl[i]];
32         return ret;
33     }
34     for(int i=l;inbl[i]==inbl[l];i++) ret+=num[i]+kadd[inbl[i]];
35     for(int i=r;inbl[i]==inbl[r];i--) ret+=num[i]+kadd[inbl[i]];
36     for(int i=inbl[l]+1;i<inbl[r];i++) ret+=ksum[i]+kadd[i]*kl;
37     return ret;
38 }
39 int main()
40 {
41     scanf("%d",&n);
42     kl=sqrt(n);
43     for(int i=1;i<=n;i++)
44     {
45         scanf("%lld",&num[i]);
46         inbl[i]=(i-1)/kl+1;
47         ksum[inbl[i]]+=num[i];
48     }
49     scanf("%d",&m);
50     int op,a,b;
51     ll c;
52     while(m--)
53     {
54         scanf("%d%d%d",&op,&a,&b);
55         if(op==1)
56         {
57             scanf("%lld",&c);
58             change(a,b,c);
59         }
60         else if(op==2)
61         {
62             printf("%lld\n",ask_sum(a,b));
63         }
64     }
65     return 0;
66 }

禁忌·树链剖分,支持树上两点间的搞事,代码极其长且难以调试,小白慎用

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 const int N=3e4+5;
  9 int n,m;
 10 int num[N];
 11 struct edge{
 12     int from,to;
 13 }e[N<<1];
 14 int head[N],nxt[N<<1],tot=0;
 15 void adde(int f,int t)
 16 {
 17     e[++tot]=(edge){f,t};
 18     nxt[tot]=head[f];
 19     head[f]=tot;
 20 }
 21 int deep[N],fa[N],siz[N],hson[N],top[N];
 22 int inseg[N],intr[N],ds=0;
 23 void dfs1(int t,int f)
 24 {
 25     deep[t]=deep[f]+1;
 26     fa[t]=f;
 27     siz[t]=1;
 28     for(int i=head[t];i;i=nxt[i])
 29     {
 30         int v=e[i].to;
 31         if(v!=f)
 32         {
 33             dfs1(v,t);
 34             siz[t]+=siz[v];
 35             if(!hson[t]||siz[v]>siz[hson[t]]) hson[t]=v;
 36         }
 37     }
 38 }
 39 void dfs2(int t,int tp)
 40 {
 41     top[t]=tp;
 42     inseg[t]=++ds;
 43     intr[ds]=t;
 44     if(!hson[t]) return;
 45     dfs2(hson[t],tp);
 46     for(int i=head[t];i;i=nxt[i])
 47     {
 48         int v=e[i].to;
 49         if(v!=fa[t]&&v!=hson[t]) dfs2(v,v);
 50     }
 51 }
 52 struct seg{
 53     int l,r;
 54     int sum,maxx;
 55 }tree[N<<2];
 56 inline void update(int p)
 57 {
 58     tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
 59     tree[p].maxx=max(tree[p<<1].maxx,tree[p<<1|1].maxx);
 60 }
 61 void build(int p,int l,int r)
 62 {
 63     tree[p].l=l;
 64     tree[p].r=r;
 65     if(l==r)
 66     {
 67         tree[p].sum=num[intr[l]];
 68         tree[p].maxx=num[intr[l]];
 69         return;
 70     }
 71     int mid=l+r>>1;
 72     build(p<<1,l,mid);
 73     build(p<<1|1,mid+1,r);
 74     update(p);
 75 }
 76 void change(int p,int pos,int v)
 77 {
 78     if(tree[p].l==tree[p].r)
 79     {
 80         tree[p].sum=v;
 81         tree[p].maxx=v;
 82         return;
 83     }
 84     int mid=tree[p].l+tree[p].r>>1;
 85     if(pos<=mid) change(p<<1,pos,v);
 86     else change(p<<1|1,pos,v);
 87     update(p);
 88 }
 89 int ask_sum(int p,int l,int r)
 90 {
 91     if(l<=tree[p].l&&r>=tree[p].r)
 92     {
 93         return tree[p].sum;
 94     }
 95     int mid=tree[p].l+tree[p].r>>1;
 96     int ret=0;
 97     if(l<=mid) ret+=ask_sum(p<<1,l,r);
 98     if(r>mid) ret+=ask_sum(p<<1|1,l,r);
 99     return ret;
100 }
101 int ask_maxx(int p,int l,int r)
102 {
103     if(l<=tree[p].l&&r>=tree[p].r)
104     {
105         return tree[p].maxx;
106     }
107     int mid=tree[p].l+tree[p].r>>1;
108     int ret=-2147483647;
109     if(l<=mid) ret=max(ret,ask_maxx(p<<1,l,r));
110     if(r>mid) ret=max(ret,ask_maxx(p<<1|1,l,r));
111     return ret;
112 }
113 int find_sum(int x,int y)
114 {
115     int fx=top[x],fy=top[y];
116     int ret=0;
117     while(fx!=fy)
118     {
119         if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy);
120         ret+=ask_sum(1,inseg[fx],inseg[x]);
121         x=fa[fx],fx=top[x];
122     }
123     if(deep[x]<deep[y]) swap(x,y);
124     ret+=ask_sum(1,inseg[y],inseg[x]);
125     return ret;
126 }
127 int find_maxx(int x,int y)
128 {
129     int fx=top[x],fy=top[y];
130     int ret=-2147483647;
131     while(fx!=fy)
132     {
133         if(deep[fx]<deep[fy]) swap(x,y),swap(fx,fy);
134         ret=max(ret,ask_maxx(1,inseg[fx],inseg[x]));
135         x=fa[fx],fx=top[x];
136     }
137     if(deep[x]<deep[y]) swap(x,y);
138     ret=max(ret,ask_maxx(1,inseg[y],inseg[x]));
139     return ret;
140 }
141 int main()
142 {
143     scanf("%d",&n);
144     int a,b;
145     for(int i=1;i<=n-1;i++)
146     {
147         scanf("%d%d",&a,&b);
148         adde(a,b);
149         adde(b,a);
150     }
151     dfs1(1,0);
152     dfs2(1,1);
153     for(int i=1;i<=n;i++) scanf("%d",&num[i]);
154     build(1,1,n);
155     scanf("%d",&m);
156     char op[10];
157     while(m--)
158     {
159         scanf("%s%d%d",op,&a,&b);
160         if(op[1]=='S') printf("%d\n",find_sum(a,b));
161         else if(op[1]=='M') printf("%d\n",find_maxx(a,b));
162         else if(op[1]=='H') change(1,inseg[a],b);
163     }
164     return 0;
165 }

先整理这么多(不要跟我说LCT之类的,我不会啊QAQ)

posted @ 2017-11-04 15:13  Frank喵^_^  阅读(229)  评论(3编辑  收藏  举报