zoukankan      html  css  js  c++  java
  • ACM模板(持续更新)

    数据的离散化存储+去重

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+7;
     4 int a[maxn];
     5 vector<int> g;
     6 int getid(int x)
     7 {
     8     return lower_bound(g.begin(),g.end(),x)-g.begin()+1;
     9 }
    10 int main()
    11 {
    12     int n;
    13     cin>>n;
    14     for(int i=0;i<n;++i){
    15         cin>>a[i];
    16         g.push_back(a[i]);
    17     }
    18     sort(g.begin(),g.end());
    19     g.erase(unique(g.begin(),g.end()),g.end());
    20     return 0;
    21 }
    View Code

    KMP

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstring>
     4 using namespace std;
     5 void get_next(char *str,int *next,int len)
     6 {
     7     int i=0,j=-1;
     8     next[0]=-1;
     9     while(i<len)
    10     {
    11         if(j==-1||str[i]==str[j]){
    12             ++i;
    13             ++j;
    14             next[i]=j;
    15         }else
    16             j=next[j];
    17     }
    18 }
    19 int Index_KMP(char *s1,char *s2,int len1,int len2)
    20 {
    21     int i=0,j=-1;
    22     int next[200];
    23     get_next(s2,next,len2);
    24     while(i<len1&&j<len2)
    25     {
    26         if(j==-1||s1[i]==s2[j]){
    27             ++i;
    28             ++j;
    29         }else
    30             j=next[j];
    31     }
    32     if(j>=len2)
    33         return i-j+1;
    34     else
    35         return 0;
    36 }
    37 int main()
    38 {
    39     char s1[200],s2[200];
    40     cin>>s1>>s2;
    41     int len1=strlen(s1);
    42     int len2=strlen(s2);
    43     int pos=Index_KMP(s1,s2,len1,len2);
    44     cout<<pos<<endl;
    45     return 0;
    46 }
    View Code

    AC自动机(指针版)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e6+7;
     4 typedef struct node{
     5     char c;
     6     struct node *next[26];
     7     struct node *fail,*father;
     8     bool flag;
     9     void init()
    10     {
    11         for(int i=0;i<26;++i)
    12             next[i]=NULL;
    13         flag=false;
    14     }
    15 } node;
    16 node *root=new node;
    17 void build(char str[][10010],int num)
    18 {
    19     int len,x;
    20     node *p,*r;
    21     root->fail=root;
    22     for(int i=0;i<num;++i){
    23         p=root;
    24         len=strlen(str[i]);
    25         for(int j=0;j<len;++j){
    26             x=str[i][j]-'a';
    27             if(!p->next[x]){
    28                 p->next[x]=new node;
    29                 p->next[x]->init();
    30                 p->next[x]->fail=root;
    31                 p->next[x]->father=p;
    32                 p->next[x]->c=str[i][j];
    33             }
    34             p=p->next[x];
    35             if(j==len-1)
    36                 p->flag=true;
    37         }
    38     }
    39     queue<node*> q;
    40     q.push(root);
    41     while(!q.empty())
    42     {
    43         p=q.front();
    44         q.pop();
    45         for(int i=0;i<26;++i){
    46             if(p->next[i])
    47                 q.push(p->next[i]);
    48         }
    49         if(p==root)
    50             continue;
    51         x=p->c-'a';
    52         r=p->father->fail;
    53         if(r->next[x]&&r->next[x]!=p)
    54             p->fail=r->next[x];
    55     }
    56 }
    57 int AC_automachine(char str[])
    58 {
    59     int ans=0,len=strlen(str),x;
    60     node *p=root;
    61     for(int i=0;i<len;++i){
    62         x=str[i]-'a';
    63         if(p->next[x]){
    64             p=p->next[x];
    65             if(p->flag)
    66                 ans++;
    67         }else{
    68             p=p->fail;
    69             if(p->flag)
    70                 ans++;
    71             if(p!=root)
    72                 --i;
    73         }
    74         //cout<<i<<endl;
    75     }
    76     return ans;
    77 }
    78 char str[51][10010];
    79 char s[maxn];
    80 int main()
    81 {
    82     cin.tie(0);
    83     ios::sync_with_stdio(false);
    84     //freopen("in.txt","r",stdin);
    85     int n,t;
    86     cin>>t;
    87     while(t--)
    88     {
    89         root->init();
    90         cin>>n;
    91         for(int i=0;i<n;++i)
    92             cin>>str[i];
    93         build(str,n);
    94         cin>>s;
    95         cout<<AC_automachine(s)<<endl;
    96     }
    97     return 0;
    98 }
    View Code

    AC自动机(数组版)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=1e6+7;
      4 const int N=5e5+7;
      5 struct Aho{
      6     struct Node{
      7         int next[26];
      8         int fail,cnt;
      9     }node[N];
     10     int size;
     11     void init()
     12     {
     13         for(int i=0;i<N;++i){
     14             memset(node[i].next,0,sizeof(node[i].next));
     15             node[i].fail=node[i].cnt=0;
     16         }
     17         size=1;
     18     }
     19     void insert(char *str)
     20     {
     21         int len=strlen(str);
     22         int now=0;
     23         for(int i=0;i<len;++i){
     24             int x=str[i]-'a';
     25             if(!node[now].next[x])
     26                 node[now].next[x]=size++;
     27             now=node[now].next[x];
     28         }
     29         node[now].cnt++;
     30     }
     31     void build()//构建fail指针
     32     {
     33         queue<int> q;
     34         node[0].fail=-1;
     35         q.push(0);
     36         while(!q.empty())
     37         {
     38             int u=q.front();
     39             q.pop();
     40             for(int i=0;i<26;++i){
     41                 if(node[u].next[i]){
     42                     if(u==0)//如果是根节点的子节点,那么fail指针一定指向根
     43                         node[node[u].next[i]].fail=0;
     44                     else{
     45                         int v=node[u].fail;
     46                         while(v!=-1)
     47                         {
     48                             if(node[v].next[i]){//如果父节点的fail指针指向的节点指向点有对应的子节点,
     49                                     //就将fail指针指向此节点
     50                                 node[node[u].next[i]].fail=node[v].next[i];
     51                                 break;
     52                             }
     53                             v=node[v].fail;
     54                         }
     55                         if(v==-1)
     56                             node[node[u].next[i]].fail=0;
     57                     }
     58                     q.push(node[u].next[i]);
     59                 }
     60             }
     61         }
     62     }
     63     int get(int u)
     64     {
     65         int ans=0;
     66         while(u)
     67         {
     68             ans+=node[u].cnt;
     69             node[u].cnt=0;
     70             u=node[u].fail;
     71         }
     72         return ans;
     73     }
     74     int math(char *s)
     75     {
     76         int len=strlen(s);
     77         int ans=0,now=0;
     78         for(int i=0;i<len;++i){
     79             int x=s[i]-'a';
     80             if(node[now].next[x])
     81                 now=node[now].next[x];
     82             else{
     83                 int p=node[now].fail;
     84                 while(p!=-1&&node[p].next[x]==0)
     85                     p=node[p].fail;
     86                 if(p==-1)
     87                     now=0;
     88                 else
     89                     now=node[p].next[x];
     90             }
     91             if(node[now].cnt)
     92                 ans+=get(now);
     93         }
     94         return ans;
     95     }
     96 }aho;
     97 char s[maxn];
     98 int main()
     99 {
    100     ios::sync_with_stdio(false);
    101     int t,n;
    102     cin>>t;
    103     while(t--)
    104     {
    105         aho.init();
    106         cin>>n;
    107         for(int i=0;i<n;++i){
    108             cin>>s;
    109             aho.insert(s);
    110         }
    111         aho.build();
    112         cin>>s;
    113         int ans=aho.math(s);
    114         cout<<ans<<endl;
    115     }
    116     return 0;
    117 }
    View Code

    并查集

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const  int maxn=1010;
     4 
     5 void Init(int *father,int *rank)
     6 {
     7     for(int i=0;i<maxn;++i){
     8         father[i]=i;
     9         rank[i]=0;
    10     }
    11 }
    12 //int FindSet1(int x,int *father)
    13 //{
    14 //    int r=x,j;
    15 //    while(x!=father[x])
    16 //        x=father[x];
    17 //    while(r!=x)
    18 //    {
    19 //        j=father[r];
    20 //        father[r]=x;
    21 //        r=j;
    22 //    }
    23 //    return x;
    24 //}
    25 int FindSet2(int x,int *father)
    26 {
    27 
    28     if(x!=father[x])
    29         father[x]=FindSet2(father[x],father);
    30     return father[x];
    31 }
    32 bool Union(int x,int y,int *father,int *rank)
    33 {
    34     x=FindSet1(x,father);
    35     y=FindSet1(y,father);
    36     if(x==y)
    37         return false;
    38     if(rank[x]>rank[y])
    39         father[y]=x;
    40     else{
    41         if(rank[x]==rank[y])
    42             rank[y]++;
    43         father[x]=y;
    44     }
    45     return true;
    46 }
    47 int main()
    48 {
    49     int n,x,y;
    50     int father[maxn],rank[maxn];
    51     Init(father,rank);
    52     cin>>n;
    53     for(int i=0;i<n;++i){
    54         cin>>x>>y;
    55         bool flag=Union(x,y,father,rank);
    56         if(flag)
    57             cout<<"Successful"<<endl;
    58         else
    59             cout<<"Set has exist"<<endl;
    60     }
    61     return 0;
    62 }
    View Code

    二分查找

     1 #include<stdio.h>
     2 
     3 int search(int tar,int a[],int len)
     4 {
     5     int ret=-1;
     6     int left=0,right=len-1,mid;
     7     while(right>left)
     8     {
     9         mid=(right+left)/2;
    10         if(a[mid]==tar){
    11             ret=mid;
    12             break;
    13         }else if(a[mid]>tar){
    14             right=mid-1;
    15         }else{
    16             left=mid+1;
    17         }
    18     }
    19     return ret;
    20 }
    21 int main()
    22 {
    23     int n,i;
    24     int a[]={1,2,7,8,18,45,66,67,88,169,198};
    25     scanf("%d",&n);
    26     i=search(n,a,sizeof(a)/sizeof(a[0]));
    27     printf("%d
    ",i);
    28     return 0;
    29 }
    View Code

    矩阵快速幂

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int NUM=5;
     5 const int mod=998244353;
     6 struct Mat{
     7     int n,m;
     8     ll a[NUM][NUM];
     9 };
    10 Mat mul(Mat a,Mat b)
    11 {
    12     Mat ans;
    13     ans.n=a.n;
    14     ans.m=b.m;
    15     for(int i=0;i<ans.n;++i)
    16     for(int j=0;j<ans.m;++j){
    17         ans.a[i][j]=0;
    18         for(int k=0;k<a.m;++k){
    19             ans.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod;
    20             ans.a[i][j]%=mod;
    21         }
    22     }
    23     return ans;
    24 }
    25 Mat power(Mat a,int num)
    26 {
    27     Mat ans;
    28     ans.n=2;
    29     ans.m=1;
    30     ans.a[0][0]=ans.a[1][0]=1;
    31     while(num)
    32     {
    33         if(num&1)
    34             ans=mul(ans,a);
    35         num>>=1;
    36         a=mul(a,a);
    37     }
    38     return ans;
    39 }
    40 int main()
    41 {
    42     //freopen("data.txt","r",stdin);
    43     //freopen("out1.txt","w",stdout);
    44     ios::sync_with_stdio(false);
    45     int n;
    46     Mat a;
    47     a.n=a.m=2;
    48     a.a[0][0]=0;
    49     a.a[0][1]=a.a[1][0]=a.a[1][1]=1;
    50     while(cin>>n)
    51     {
    52         Mat ans=power(a,n*2+3);
    53         cout<<((ans.a[0][1]-1)%mod+mod)%mod<<endl;
    54     }
    55     return 0;
    56 }
    View Code

    欧几里得

    1 int gcd(int a,int b)
    2 {
    3     return b==0?a:gcd(b,a%b);
    4 }
    View Code

    拓展欧几里得

     1 int exGcd(a a,a b,a &x,a &y)
     2 {
     3     if(b==0){
     4         x=1;y=0;
     5         return a;
     6     }
     7     int r=exGcd(b,a%b,x,y);
     8     int t=x;
     9     x=y;
    10     y=t-a/b*y;
    11 }
    View Code

    线性筛

     1 const int maxn=1e6+10;
     2 bool isprime[maxn];
     3 int prime[maxn];
     4 int primenum;
     5 void getprime(int limit)
     6 {
     7     primenum=0;
     8     memset(isprime,true,sizeof(isprime));
     9     isprime[0]=isprime[1]=false;
    10     for(int i=2;i<=limit;++i){
    11         if(isprime[i])
    12             prime[++primenum]=i;
    13         for(int j=1;j<=primenum&&i*prime[j]<=limit;++j){
    14             isprime[i*prime[j]]=false;
    15             if(i%prime[j]==0)
    16                 break;
    17         }
    18     }
    19 }
    View Code

    较小组合数求模

     1 int num[maxn][maxn];
     2 int C(int n,int k)
     3 {
     4     if(k>n)
     5         return 0;
     6     return num[n][k];
     7 }
     8 void Cal(int n)
     9 {
    10     for(int i=0;i<=n;++i){
    11         num[i][0]=1;
    12         for(int j=1;j<i;++j)
    13             num[i][j]=(C(i-1,j-1)%mod+C(i-1,j)%mod)%mod;
    14         num[i][i]=1;
    15     }
    16 }
    View Code

    矩阵乘法

    1 void mult(int **a,int **b,int **c)
    2 {
    3     memset(c,0,sizeof(c));
    4     for(int i=0;i<N;++i)
    5         for(int j=0;j<N;++j)
    6             for(int l=0;l<N;++l)
    7                 c[i][j]+=a[i][l]*b[l][j];
    8 }
    View Code

    求逆元

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 void ex_gcd(LL a,LL b,LL &x,LL &y,LL &d)
     5 {
     6     if(!b)
     7         d=a,x=1,y=0;
     8     else {
     9         ex_gcd(b,a%b,y,x,d);
    10         y-=x*(a/b);
    11     }
    12 }
    13 LL inv1(LL a,LL p)
    14 {
    15      LL d,x,y;
    16      ex_gcd(a,p,x,y,d);
    17      return d==1?(x%p+p)%p:-1;
    18 }
    19 LL inv2(LL a,LL p)
    20 {
    21     return a==1?1:(p-p/a)*inv(p%t,p)%p;
    22 }
    23 int main()
    24 {
    25     LL a,p;
    26     while(cin>>a>>p)
    27         cout<<inv1(a,p)<<endl;
    28     return 0;
    29 }
    View Code

    欧拉函数

     1 //欧拉函数是求小于等于n的数中与n互质的数的数目
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 const int maxn=1e6+7;
     5 int phi[maxn],prime[maxn];
     6 int tot;
     7 void Euler()
     8 {
     9     phi[1]=1;
    10     for(int i=2;i<N;++i){
    11         if(!phi[i]){
    12             phi[i]=i-1;
    13             prime[tot++]=i;
    14         }
    15         for(int j=0;j<tot&&i*prime[j]<maxn;++j){
    16             if(i%prime[j])
    17                 phi[i*prime[j]]=phi[i]*(prime[j]-1);
    18             else{
    19                 phi[i*prime[j]]=phi[i]*prime[j];
    20                 break;
    21             }
    22         }
    23     }
    24 }
    25 int main()
    26 {
    27     Euler();
    28     return 0;
    29 }
    View Code

    中国剩余定理

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3  //n个方程:x=a[i](mod m[i]) (0<=i<n)
     4  LL china(int n, LL *a, LL *m){
     5      LL M = 1, ret = 0;
     6      for(int i = 0; i < n; i ++) M *= m[i];
     7      for(int i = 0; i < n; i ++){
     8         LL w = M / m[i];
     9         ret = (ret + w * inv(w, m[i]) * a[i]) % M;
    10     }
    11     return (ret + M) % M;
    12  }
    View Code

    Lucas定理

    1 LL Lucas(LL n, LL m, int p)
    2 {
    3          return m ? Lucas(n/p, m/p, p) * comb(n%p, m%p, p) % p : 1;
    4 }
    View Code

    高精度求模

    1 int get_mod(string a,int mod)
    2 {
    3     int ans=0;
    4     for(int i=0;i<a.size();++i)
    5         ans=(ans*10+(a[i]-'0'))%mod;
    6     return ans;
    7 }
    View Code

    莫队算法

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn=1e6+7;
     5 struct node{
     6     int l,r,id;
     7 }query[maxn];
     8 ll Ans=0,a[i],ans[maxn];
     9 int pos[maxn],L=0,R=1;
    10 bool cmp(node a,node b)
    11 {
    12     if(pos[a.l]==pos[b.l])
    13         return a.r<b.r;
    14     return pos[a.l]<pos[b.l];
    15 }
    16 void add(int x)
    17 {
    18 
    19 }
    20 
    21 void del(int x)
    22 {
    23 
    24 }
    25 int main()
    26 {
    27     int n,m,sz;
    28     cin>>n>>m;
    29     sz=sqrt(n);
    30     for(int i=1;i<=n;++i){
    31         cin>>a[i];
    32         a[i]+=a[i-1];
    33         pos[i]=i/sz;
    34     }
    35     for(int i=1;i<=m;++i){
    36         cin>>query[i].l>>query[i].r;
    37         query[i].id=i;
    38     }
    39     sort(query+1,query+1+m);
    40     for(int i=1;i<=m;++i){
    41         while(L<query[i].l)
    42         {
    43             del(L-1);
    44             ++L;
    45         }
    46         while(L>query[i].l)
    47         {
    48             --L;
    49             add(L-1);
    50         }
    51         while(R<query[i].r)
    52         {
    53             ++R;
    54             add(R);
    55         }
    56         while(R>query[i].r)
    57         {
    58             del(R);
    59             --R;
    60         }
    61         ans[query[i].id]=Ans;
    62     }
    63     for(int i=1;i<=m;++i)
    64         cout<<ans[i]<<endl;
    65     return 0;
    66 }
    View Code

    线段树(点修改)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=100010;
     4 int a[maxn],tree[maxn*2];
     5 void build(int l,int r,int k)
     6 {
     7     if(l>r)
     8         return ;
     9     if(l==r)
    10         tree[k]=a[l];
    11     int mid=(l+r)>>1;
    12     build(l,mid,2*k);
    13     build(mid+1,r,2*k+1);
    14     tree[k]=tree[2*k]+tree[2*k+1];
    15 }
    16 void change(int l,int r,int cl,int cr,int k,int x)
    17 {
    18     if(l>cr||r<cl||l>r)
    19         return ;
    20     if(l==r){
    21         tree[k]+=x;
    22         return;
    23     }
    24     int mid=(l+r)>>1;
    25     change(l,mid,cl,cr,2*k,x);
    26     change(mid+1,r,cl,cr,2*k+1,x);
    27     tree[k]=tree[k]=tree[2*k]+tree[2*k+1];
    28 }
    29 int query(int l,int r,int ql,int qr,int k)
    30 {
    31     if(l>cr||r<cl||l>r)
    32         return 0;
    33     if(l>ql&&r<qr)
    34         return tree[k];
    35     int mid=(l+r)>>1;
    36     return query(l,mid,ql,qr,2*k)+query(mid+1,r,ql,qr,2*k+1);
    37 }
    38 int main()
    39 {
    40     int n;
    41     cin>>n;
    42     for(int i=1;i<=n;++i)
    43         cin>>a[i];
    44     build(1,n,1);
    45 
    46     return 0;
    47 }
    View Code

    线段树(区间修改)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+10;
     4 int a[maxn];
     5 int sum[maxn<<2],exc[maxn<<2];
     6 void maintain(int k)
     7 {
     8     sum[k]=sum[k<<1]+sum[k<<1|1];
     9 }
    10 void pushdown(int lenl,int lenr,int k)//标记下放,并更细节点信息
    11 {
    12     if(exc[k]){
    13         exc[k<<1]=exc[k];
    14         exc[k<<1|1]=exc[k];
    15         sum[k<<1]=exc[k]*lenl;
    16         sum[k<<1|1]=exc[k]*lenr;
    17         exc[k]=0;
    18     }
    19 }
    20 void build(int l,int r,int k)
    21 {
    22     if(l>r)
    23         return ;
    24     if(l==r){
    25         sum[k]=a[l];
    26         exc[k]=0;
    27         return ;
    28     }
    29     int mid=(l+r)>>1;
    30     build(l,mid,k<<1);
    31     build(mid+1,r,k<<1|1);
    32     maintain(k);
    33 }
    34 void change(int l,int r,int cl,int cr,int k,int newp)
    35 {
    36     if(l>r||cl>r||cr<l)
    37         return ;
    38     if(l>=cl&&r<=cr){
    39         sum[k]=newp*(r-l+1);//在发现现在区域小于需要更新区域时
    40         exc[k]=newp;//更新节点的结果,并增加延迟标记exc,用于之后的标记下放
    41         return ;
    42     }
    43     int mid=(l+r)>>1;
    44     pushdown(mid-l+1,r-mid,k);
    45     change(l,mid,cl,cr,k<<1,newp);
    46     change(mid+1,r,cl,cr,k<<1|1,newp);
    47     maintain(k);
    48 }
    49 int query(int l,int r,int ql,int qr,int k)
    50 {
    51     if(l>r||ql>r||qr<l)
    52         return 0;
    53     if(l>=ql&&r<=qr)
    54         return sum[k];
    55     int mid=(l+r)>>1,ans=0;
    56     pushdown(mid-l+1,r-mid,k);//每一层询问执行到这一步,为了下一次递归更新叶节点信息
    57     if(mid>=l)
    58         ans+=query(l,mid,ql,qr,k<<1);
    59     if(mid<r)
    60         ans+=query(mid+1,r,ql,qr,k<<1|1);
    61     return ans;
    62 }
    63 int main()
    64 {
    65     ios::sync_with_stdio(false);
    66     //freopen("in.txt","r",stdin);
    67     int n,m,cmd,l,r,newp;
    68     cin>>n;
    69     for(int i=1;i<=n;++i)
    70         cin>>a[i];
    71     build(1,n,1);
    72     cin>>m;
    73     for(int i=0;i<m;++i){
    74         cin>>cmd>>l>>r;
    75         if(cmd){
    76             cin>>newp;
    77             change(1,n,l,r,1,newp);
    78         }else
    79             cout<<query(1,n,l,r,1)<<endl;
    80     }
    81     return 0;
    82 }
    View Code

    树上倍增

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+7;
     4 vector<int> mp[maxn];
     5 int dep[maxn],fa[maxn][40],size[maxn];
     6 void dfs(int x,int last)
     7 {
     8     int v;
     9     dep[x]=dep[last]+1;
    10     fa[x][0]=last;
    11     size[x]=1;
    12     for(int i=0;i<mp[x].size();++i){
    13         v=mp[x][i];
    14         if(v!=last){
    15             dfs(v,x);
    16             size[x]+=size[i];
    17         }
    18     }
    19 }
    20 int lca(int a,int b,int n)
    21 {
    22     for(int j=1;j<=20;++j)
    23         for(int i=1;i<=n;++i)
    24             fa[i][j]=fa[fa[i][j-1]][j-1];
    25     if(dep[a]<dep[b])
    26         swap(a,b);
    27     int d=dep[a]-dep[b];
    28     for(int i=0;i<=20;++i)
    29         if((1<<i)&d)
    30             a=fa[a][d];
    31     for(int i=20;i>=0;--i)
    32     if(fa[a][i]!=fa[b][i]){
    33         a=fa[a][i];
    34         b=fa[b][i];
    35     }
    36     if(a==b)
    37         return a;
    38     else
    39         return fa[a][0];
    40 }
    41 int main()
    42 {
    43     int n,u,v;
    44     cin>>n;
    45     for(int i=0;i<n;++i){
    46         cin>>u>>V;
    47         mp[u].push_back(v);
    48         mp[v].push_back(u);
    49     }
    50     dfs(1,0);
    51     cin>>u>>v;
    52     cout<<lca(u,v,n)<<endl;
    53     return 0;
    54 }
    View Code

    树链剖分

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=3e4+7;
      4 const int INF=1<<30;
      5 int weight[maxn],id[maxn],son[maxn],dep[maxn];
      6 int father[maxn],size[maxn],root[maxn];
      7 int idx=0;
      8 struct node{
      9     int l,r;
     10     int maxx,sum;
     11 }tree[maxn<<2];
     12 vector<int> g[maxn];
     13 void dfs(int x,int last,int d)
     14 {
     15     dep[x]=d;
     16     size[x]=1;
     17     father[x]=last;
     18     son[x]=0;
     19     int v;
     20     for(int i=0;i<g[x].size();++i){
     21         v=g[x][i];
     22         if(v==last)
     23             continue;
     24         dfs(v,x,d+1);
     25         if(i==0)
     26             son[x]=v;
     27         else if(size[son[x]]<size[v])
     28             son[x]=v;
     29         size[x]+=size[v];
     30     }
     31 }
     32 void connect(int x,int r)
     33 {
     34     int v;
     35     root[x]=r;
     36     id[x]=++idx;
     37     if(son[x]!=0){
     38         connect(son[x],r);
     39         for(int i=0;i<g[x].size();++i){
     40             v=g[x][i];
     41             if(v!=father[x]&&v!=son[x])
     42                 connect(v,v);
     43         }
     44     }
     45 }
     46 void build(int l,int r,int k)
     47 {
     48     if(l>r)
     49         return ;
     50     tree[k].l=l;
     51     tree[k].r=r;
     52     if(l==r)
     53         return ;
     54     int mid=(l+r)>>1;
     55     build(l,mid,k<<1);
     56     build(mid+1,r,k<<1|1);
     57 }
     58 void change(int tar,int w,int k)
     59 {
     60     int l=tree[k].l;
     61     int r=tree[k].r;
     62     if(l==r){
     63         tree[k].maxx=w;
     64         tree[k].sum=w;
     65         return ;
     66     }
     67     int mid=(l+r)>>1;
     68     if(tar<=mid)
     69         change(tar,w,k<<1);
     70     else
     71         change(tar,w,k<<1|1);
     72     tree[k].maxx=max(tree[k<<1].maxx,tree[k<<1|1].maxx);
     73     tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
     74 }
     75 int query_max(int ql,int qr,int k)
     76 {
     77     int l=tree[k].l;
     78     int r=tree[k].r;
     79     if(ql>r||qr<l)
     80         return -INF;
     81     if(ql<=l&&qr>=r)
     82         return tree[k].maxx;
     83     int mid=(l+r)>>1;
     84     return max(query_max(ql,qr,k<<1),query_max(ql,qr,k<<1|1));
     85 }
     86 int query_sum(int ql,int qr,int k)
     87 {
     88     int l=tree[k].l;
     89     int r=tree[k].r;
     90     if(ql>r||qr<l)
     91         return 0;
     92     if(ql<=l&&qr>=r)
     93         return tree[k].sum;
     94     int mid=(l+r)>>1;
     95     return query_sum(ql,qr,k<<1)+query_sum(ql,qr,k<<1|1);
     96 }
     97 int Cal_Sum(int qa,int qb)
     98 {
     99     int sum=0;
    100     while(root[qa]!=root[qb])
    101     {
    102         if(dep[root[qa]]<dep[root[qb]])
    103             swap(qa,qb);
    104         sum+=query_sum(id[root[qa]],id[qa],1);
    105         qa=father[root[qa]];
    106 
    107     }
    108     if(id[qa]>id[qb])
    109         swap(qa,qb);
    110     sum+=query_sum(id[qa],id[qb],1);
    111     return sum;
    112 }
    113 int Cal_Max(int qa,int qb)
    114 {
    115     int maxx=-INF;
    116     while(root[qa]!=root[qb])
    117     {
    118         if(dep[root[qa]]<dep[root[qb]])
    119             swap(qa,qb);
    120         maxx=max(maxx,query_max(id[root[qa]],id[qa],1));
    121         qa=father[root[qa]];
    122     }
    123     if(id[qa]>id[qb])
    124         swap(qa,qb);
    125     maxx=max(maxx,query_max(id[qa],id[qb],1));
    126     return maxx;
    127 }
    128 int main()
    129 {
    130     //freopen("in.txt","r",stdin);
    131     int n,v,u,q;
    132     char cmd[10];
    133     scanf("%d",&n);
    134     for(int i=1;i<n;++i){
    135         scanf("%d%d",&u,&v);
    136         g[u].push_back(v);
    137         g[v].push_back(u);
    138     }
    139 
    140     for(int i=1;i<=n;++i)
    141         scanf("%d",&weight[i]);
    142     dfs(1,1,1);
    143     connect(1,1);
    144     build(1,n,1);
    145     for(int i=1;i<=n;++i)
    146         change(id[i],weight[i],1);
    147     scanf("%d",&q);
    148     for(int i=0;i<q;++i){
    149         scanf("%s%d%d",cmd,&u,&v);
    150         if(cmd[0]=='C')
    151             change(id[u],v,1);
    152         else if(cmd[1]=='S')
    153             printf("%d
    ",Cal_Sum(u,v));
    154         else
    155             printf("%d
    ",Cal_Max(u,v));
    156     }
    157     return 0;
    158 }
    View Code

    SPFA

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+7;
    const int INF=0x3F;
    struct node{
        int to,len;
    };
    vector<node> g[maxn];
    int shortlen[maxn],cnt[maxn];
    int n,m,s,t;
    bool visit[maxn];
    bool spfa()
    {
        memset(shortlen,INF,sizeof(shortlen));
        memset(visit,false,sizeof(visit));
        memset(cnt,0,sizeof(cnt));
        queue<int> q;
        q.push(s);
        shortlen[s]=0;
        visit[s]=true;
        while(!q.empty())
        {
            s=q.front();
            q.pop();
            visit[s]=false;
            for(int i=0;i<g[s].size();++i){
                if(shortlen[s]+g[s][i].len<shortlen[g[s][i].to]){
                    shortlen[g[s][i].to]=shortlen[s]+g[s][i].len;
                    if(!visit[g[s][i].to]){
                        visit[g[s][i].to]=true;
                        q.push(g[s][i].to);
                        cnt[g[s][i].to]++;
                        if(cnt[g[s][i]].to>n)
                            return false;
                    }
                }
            }
        }
        cout<<shortlen[t]<<endl;
        return true;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        //freopen("in.txt","r",stdin);
        int u,v;
        node a;
        cin>>n>>m>>s>>t;
        for(int i=0;i<m;++i){
            cin>>u>>v>>a.len;
            a.to=v;
            g[u].push_back(a);
            a.to=u;
            g[v].push_back(a);
        }
        spfa();
        return 0;
    }
    View Code

    迪杰斯特拉

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 #include<queue>
     7 using namespace std;
     8 const int INF=65535;
     9 const int maxn=110;
    10 unsigned int mp[maxn][maxn];
    11 bool visit[maxn];
    12 unsigned int shortlen[maxn];
    13 typedef struct Node{
    14     int dis,v;
    15     bool operator < (const Node &cmp) const{//重载小于号,不理解的可以直接用。作用相当于定义一个优先队列的比较规则
    16         return dis > cmp.dis;
    17     }
    18 }Node;
    19 void Dijkstra(int start,int num)
    20 {
    21     int value;
    22     memset(visit,false,sizeof(visit));
    23     memset(shortlen,INF,sizeof(shortlen));
    24     priority_queue<Node> q;
    25     shortlen[start]=0;
    26     q.push({0,start});//起点放入队列
    27     while(!q.empty())
    28     {
    29         Node a=q.top();//取出
    30         q.pop();
    31         start=a.v;
    32         value=shortlen[start];
    33         visit[start]=true;//记为访问过
    34         for(int i=1;i<=num;++i){
    35             if(i==start)
    36                 continue;
    37             if(mp[start][i]<INF&&visit[i]==false){
    38                     if(mp[start][i]+value<shortlen[i])
    39                         shortlen[i]=mp[start][i]+value;//更新数组
    40                     q.push({shortlen[i],i});
    41                }
    42         }
    43     }
    44 }
    45 int main()
    46 {
    47 //    freopen("in.txt","r",stdin);
    48     int numv;
    49     int x,y,w,v;
    50     cout<<"InPut the number of v"<<endl;
    51     cin>>numv;
    52     memset(mp,INF,sizeof(mp));
    53     cout<<"Build Map"<<endl;
    54     while(cin>>x>>y&&(x||y))
    55     {
    56         cin>>w;
    57         mp[x][y]=w;
    58         mp[y][x]=w;
    59     }
    60     cout<<"Input the start"<<endl;
    61     cin>>v;
    62 
    63     Dijkstra(v,numv);
    64     for(int i=1;i<=numv;++i)
    65         cout<<"i="<<i<<" shortlen="<<shortlen[i]<<endl;
    66     cout<<endl;
    67     return 0;
    68 }
    View Code

    克鲁斯卡尔

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=110;
     4 typedef struct{
     5     int begin,end,weight;
     6 }Edge;
     7 int FindSet(int x,int *father)
     8 {
     9 
    10     if(x!=father[x])
    11         father[x]=FindSet(father[x],father);
    12     return father[x];
    13 }
    14 bool Union(int x,int y,int *father,int *rank)
    15 {
    16     x=FindSet(x,father);
    17     y=FindSet(y,father);
    18     if(x==y)
    19         return false;
    20     if(rank[x]>rank[y])
    21         father[y]=x;
    22     else{
    23         if(rank[x]==rank[y])
    24             rank[y]++;
    25         father[x]=y;
    26     }
    27     return true;
    28 }
    29 bool cmp(Edge a,Edge b)
    30 {
    31     return a.weight<b.weight;
    32 }
    33 bool isfull(bool *flag,int n)
    34 {
    35     for(int i=0;i<n;++i){
    36         if(!flag[i])
    37             return false;
    38     }
    39     return true;
    40 }
    41 int main()
    42 {
    43    // freopen("in.txt","r",stdin);
    44     Edge a[maxn];
    45     bool flag[maxn];
    46     int v,e;
    47     cin>>v>>e;
    48     memset(flag,false,sizeof(flag));
    49     for(int i=0;i<e;++i)
    50         cin>>a[i].begin>>a[i].end>>a[i].weight;
    51     int father[maxn],rank[maxn];
    52     for(int i=0;i<v;++i){
    53         father[i]=i;
    54         rank[i]=0;
    55     }
    56     sort(a,a+e,cmp);
    57     for(int i=0;i<v;++i){
    58         if(isfull(flag,v))
    59             break;
    60         Union(a[i].begin,a[i].end,father,rank);
    61         cout<<"("<<a[i].begin<<","<<a[i].end<<")"<<endl;
    62         flag[a[i].begin]=true;
    63         flag[a[i].end]=true;
    64     }
    65     return 0;
    66 }
    View Code

    普里姆

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int INF=1<<30;
     4 const int maxn=110;
     5 typedef struct {
     6     int mp[maxn][maxn];
     7     int number;
     8 }Graph;
     9 void prim(Graph &a)
    10 {
    11     int min,i,j,k;
    12     int adj[maxn],lowcost[maxn];
    13     lowcost[0]=0;
    14     adj[0]=0;
    15     for(int i=1;i<a.number;++i){
    16         lowcost[i]=a.mp[0][i];
    17         adj[i]=0;
    18     }
    19     for(int i=1;i<a.number;++i){
    20         int min=INF;
    21         int j=1,k=0;
    22         while(j < a.number)
    23         {
    24             if( lowcost[j]!=0 && lowcost[j]<min){
    25                 min = lowcost[j];
    26                 k=j;
    27             }
    28             j++;
    29         }
    30         cout<<"("<<adj[k]<<","<<k<<")"<<endl;
    31         lowcost[k]=0;
    32         for(int j=1;j<a.number;++j){
    33             if(lowcost[j]!=0 && a.mp[k][j]<lowcost[j]){
    34                 lowcost[j]=a.mp[k][j];
    35                 adj[j]=k;
    36             }
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     freopen("in.txt","r",stdin);
    43     Graph a;
    44     int v,e,x,y,w;
    45     cin>>v>>e;
    46     a.number=v;
    47     for(int i=0;i<v;++i)
    48         for(int j=0;j<v;++j)
    49         a.mp[i][j]=INF;
    50     for(int i=0;i<v;++i)
    51         a.mp[i][i]=0;
    52     for(int i=0;i<e;++i){
    53         cin>>x>>y>>w;
    54         a.mp[x][y]=w;
    55         a.mp[y][x]=w;
    56     }
    57     prim(a);
    58     return 0;
    59 }
    View Code

    tarjan求强连通分量+缩点

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2e4+7;
     4 vector<int> g[maxn];
     5 vector<int> newp[maxn];
     6 int dfn[maxn],low[maxn],sccno[maxn];
     7 int idx=0;
     8 bool visit[maxn];
     9 stack<int> s;
    10 void tarjan(int u)
    11 {
    12     dfn[u]=low[u]=++idx;
    13     s.push(u);
    14     visit[u]=true;
    15     int v;
    16     for(int i=0;i<g[u].size();++i){
    17         v=g[u][i];
    18         if(dfn[v]==0){
    19             tarjan(v);
    20             low[u]=min(low[u],low[v]);
    21         }else if(visit[v])
    22             low[u]=min(low[u],dfn[v]);
    23     }
    24     if(dfn[u]==low[u])
    25         do{
    26             v=s.top();
    27             s.pop();
    28             sccno[v]=u;//Ëõµã
    29             visit[v]=false;
    30         }while(u!=v);
    31 }
    32 void suodian(int n)
    33 {
    34     int v,u;
    35     for(int i=1;i<=n;++i){
    36         for(int j=0;j<g[i].size();++j){
    37             u=g[i][j];
    38             if(sccno[i]==u)
    39                 continue;
    40             if(w[u]==0)
    41                 continue;
    42             if(u!=sccno[u]){
    43                 w[sccno[u]]+=w[u];
    44                 w[u]=0;
    45             }else
    46                 newp[sccno[i]].push_back(u);
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     ios::sync_with_stdio(false);
    53     //freopen("in.txt","r",stdin);
    54     int n,m,u,v;
    55     memset(dfn,0,sizeof(dfn));
    56     cin>>n>>m;
    57     for(int i=1;i<=n;++i)
    58         cin>>w[i];
    59     for(int i=1;i<=m;++i){
    60         cin>>u>>v;
    61         g[u].push_back(v);
    62     }
    63     for(int i=1;i<=n;++i)
    64         sccno[i]=i;
    65     tarjan(1);
    66     suodian(n);
    67     return 0;
    68 }
    View Code

    拓扑排序

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=110;
     4 const int INF=1<<30;
     5 int mp[maxn][maxn]£¬in[maxn];
     6 int cnt=0;
     7 bool clear(int n)
     8 {
     9     for(int i=0;i<n;++i)
    10         if(in[i])
    11             return false;
    12     return true;
    13 }
    14 void TopSort(int v,int n)
    15 {
    16     if(clear(n))
    17         return ;
    18     cnt++;
    19     cout<<v<<" ";
    20     for(int i=0;i<n;++i){
    21         if(i==v)
    22             continue;
    23         mp[i][v]=INF;
    24         if(mp[v][i]!=INF){
    25             in[i]--;
    26             mp[v][i]=INF;
    27             if(in[i]==0)
    28                 TopSort(i,n);
    29         }
    30     }
    31 }
    32 int main()
    33 {
    34     int n,m,x,y,w;
    35     memset(in,0,sizeof(in));
    36     cin>>n>>m;
    37     for(int i=0;i<n;++i)
    38         for(int j=0;j<n;++j)
    39             mp[i][j]=INF;
    40     for(int i=0;i<m;++i){
    41         cin>>x>>y>>w;
    42         mp[x][y]=w;
    43         in[y]++;
    44     }
    45     for(int i=0;i<n;++i){
    46         if(in[i]==0){
    47             TopSort(i,n);
    48             break;
    49         }
    50     }
    51     cout<<endl;
    52     if(cnt==n)
    53         cout<<"It's AOV"<<endl;
    54     else
    55         cout<<"It's not AOV"<<endl;
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    python实现双向链表
    django contenttypes
    tensorflow学习笔记一
    vue指令和事件绑定
    es6简单介绍
    mysql主从复制
    mysql事务
    winform 使用 ReportViewer做报表
    设置控件获取焦点
    修改安卓串口蓝牙app问题记录
  • 原文地址:https://www.cnblogs.com/SCaryon/p/7373338.html
Copyright © 2011-2022 走看看