• [总结]板子整理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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",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
    ",find_sum(a,b));
    161         else if(op[1]=='M') printf("%d
    ",find_maxx(a,b));
    162         else if(op[1]=='H') change(1,inseg[a],b);
    163     }
    164     return 0;
    165 }

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

  • 相关阅读:
    !!!!Linux系统开发 系列 4 进程资源 环境 fork()子进程 wait() waitpid()僵尸 孤儿进程
    linux运维工程师
    C# CSGL
    C# 中的"yield"使用
    C#语法糖
    VS2017下Git的使用
    Oracle数据类型与.NET中的对应关系
    Java 8 Stream
    Java 8 默认方法
    Java 8 函数式接口
  • 原文地址:https://www.cnblogs.com/loi-frank/p/7783435.html
Copyright © 2020-2023  润新知