• 模板(按照洛谷顺序)


    对拍(详见注释)

     1 #include<stdio.h>
     2 #include<windows.h>
     3 using namespace std;
     4 int main()
     5 {
     6     int n=100000;
     7     while(n--)
     8     {
     9         system("data.exe>data.in");//运行data.exe导入data.in 
    10         system("myCode.exe<data.in>myCode.out");//用data.in的数据运行待测程序导入out文件
    11         system("correctCode.exe<data.in>correctCode.out");//用data.in的数据运行对拍程序导入out文件
    12         if(system("fc myCode.out correctCode.out")) break;//比较输出结果
    13     }
    14     system("pause");
    15     return 0;
    16 }
    show you the code

    负环

    (spfa中一个点被松弛(放入队列中)n次,一定有负环)

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 using namespace std;
     5 const int N=2010;
     6 const int M=3010;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 
    15 struct node
    16 {
    17     int nxt,to,dis;
    18 }g[M<<1];
    19 int head[N],tot;
    20 int T,n,m;
    21 int dist[N],cnt[N];
    22 bool vis[N];
    23 
    24 I void addedge(int u,int v,int dis)
    25 {
    26     g[++tot].nxt=head[u];
    27     g[tot].to=v;
    28     g[tot].dis=dis;
    29     head[u]=tot;
    30 }
    31 
    32 I bool spfa()
    33 {
    34     memset(vis,0,sizeof(vis));
    35     memset(cnt,0,sizeof(cnt));
    36     memset(dist,127,sizeof(dist));
    37     queue<int>q;q.push(1);vis[1]=0;dist[1]=0;
    38     while(q.size())
    39     {
    40         int u=q.front();q.pop();vis[u]=0;
    41         for(int i=head[u];i;i=g[i].nxt)
    42         {
    43             int v=g[i].to;
    44             if(dist[v]>dist[u]+g[i].dis)
    45             {
    46                 cnt[v]=cnt[u]+1;
    47                 if(cnt[v]>n)return 1;
    48                 dist[v]=dist[u]+g[i].dis;
    49                 if(!vis[v])vis[v]=1,q.push(v);
    50             }
    51         }
    52     }
    53     return 0;
    54 }
    55                 
    56 
    57 int main()
    58 {
    59     T=read();
    60     while(T--)
    61     {
    62         n=read();m=read();tot=0;
    63         memset(head,0,sizeof(head));
    64         for(int i=1;i<=m;i++)
    65         {
    66             int x=read(),y=read(),z=read();
    67             if(z<0)addedge(x,y,z);
    68             else addedge(y,x,z),addedge(x,y,z);
    69         }
    70         if(spfa())puts("YE5");
    71         else puts("N0");
    72     }
    73 }
    show you the code

    缩点

    (tarjan+toposort+dp基操)

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 using namespace std;
     5 const int N=1e4+10;
     6 const int M=1e5+10;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int n,m;
    15 int val[N];
    16 vector<int>g[N],e[N];
    17 int dfn[N],low[N],sta[N],col[N],color,ind,top;
    18 int p[N],in[N],dp[N],ans;
    19 
    20 I void tarjan(int u)
    21 {
    22     low[u]=dfn[u]=++ind;
    23     sta[++top]=u;
    24     for(int i=0;i<g[u].size();i++)
    25     {
    26         int v=g[u][i];
    27         if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
    28         else if(!col[v])low[u]=min(low[u],dfn[v]);
    29     }
    30     if(low[u]==dfn[u])
    31     {
    32         color++;
    33         while(sta[top]!=u)
    34         {
    35             col[sta[top]]=color;
    36             p[color]+=val[sta[top]];
    37             top--;
    38         }top--;col[u]=color;
    39         p[color]+=val[u];
    40     }
    41 }
    42 
    43 I void topo()
    44 {
    45     queue<int>q;
    46     for(int i=1;i<=color;i++)
    47     {
    48         if(!in[i])q.push(i),dp[i]=p[i];
    49     }
    50     while(!q.empty())
    51     {
    52         int u=q.front();q.pop();ans=max(ans,dp[u]);
    53         for(int i=0;i<e[u].size();i++)
    54         {
    55             int v=e[u][i];
    56             in[v]--;dp[v]=max(dp[v],dp[u]+p[v]);
    57             if(!in[v])q.push(v);
    58         }
    59     }
    60     cout<<ans;
    61 }
    62 
    63 int main()
    64 {
    65     n=read();m=read();for(int i=1;i<=n;i++)val[i]=read();
    66     for(int i=1;i<=m;i++)
    67     {
    68         int x=read(),y=read();
    69         g[x].push_back(y);
    70     }
    71     for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
    72     for(int u=1;u<=n;u++)
    73     for(int i=0;i<g[u].size();i++)
    74     {
    75         int v=g[u][i];
    76         if(col[v]!=col[u])
    77         {
    78             e[col[u]].push_back(col[v]);
    79             in[col[v]]++;
    80         }
    81     }
    82     topo();
    83 }
    show you the code

    ST表

    (注意边界是$l+2^{k}-1$,询问的时候右边区间从$r-2^{k}+1$开始,即找一个x使$x+x^{k}-1=r$

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 using namespace std;
     5 const int N=1e5+10;
     6 const int M=1e6+10;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int n,m;
    15 int f[N][25];
    16 
    17 I void ST()
    18 {
    19     for(int j=1;(1<<j)-1<=n;j++)
    20     for(int i=1;i+(1<<j)-1<=n;i++)
    21     f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
    22 }
    23 
    24 I int query(int l,int r)
    25 {
    26     int k=log2(r-l+1);
    27     return max(f[l][k],f[r-(1<<k)+1][k]);
    28 }
    29  
    30 int main()
    31 {
    32     n=read();m=read();for(int i=1;i<=n;i++)f[i][0]=read();
    33     ST();
    34     while(m--)
    35     {
    36         int l=read(),r=read();
    37         printf("%d
    ",query(l,r));
    38     }
    39 }
    show you the code

    动态DP

    (NOIP2018毒瘤,求树上最大带权独立集,树形DP之后,先把dp值放到数组里,全部是虚边(每个点一棵splay根),修改用$max$矩阵乘法和LCT维护,注意一下pushup的时候矩阵乘法的和深度的关系,按照$ls(x)*x*rs(x)$的顺序乘)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define I inline
      6 #define R register
      7 #define ls(x) ch[x][0]
      8 #define rs(x) ch[x][1]
      9 using namespace std;
     10 typedef long long LL;
     11 const int N=500010;
     12 const int inf=(1<<31)-1;
     13 
     14 I int read()
     15 {
     16     int x=0,f=1;char ch=getchar();
     17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     18     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     19     return x*f;
     20 }
     21 
     22 int n,m;
     23 struct node
     24 {
     25     int nxt,to;
     26 }g[N<<1];
     27 int head[N],cnt;
     28 
     29 int a[N],f[N],ch[N][2];
     30 LL dp[N][2];
     31 
     32 struct matrix
     33 {
     34     LL p[2][2];
     35     matrix(){p[0][0]=p[0][1]=p[1][0]=p[1][1]=-inf;}//新定义的矩阵乘初始化    
     36 }s[N],si[N];//s为整棵splay(实链)上点的矩阵乘积
     37 //si为x的虚子树的矩阵乘积(包括自己) 
     38 
     39 I matrix operator * (const matrix &a,const matrix &b)
     40 {
     41     matrix c;
     42     for(int i=0;i<=1;i++)
     43     for(int k=0;k<=1;k++)
     44     for(int j=0;j<=1;j++)
     45     c.p[i][j]=max(c.p[i][j],a.p[i][k]+b.p[k][j]);
     46     return c;
     47 }
     48 
     49 I void dfs(R int u)//刚开始全部是虚边,所以不区分虚实子树 
     50 {
     51     dp[u][1]=a[u];
     52     for(int i=head[u];i;i=g[i].nxt)
     53     {
     54         int v=g[i].to;
     55         if(v==f[u])continue;
     56         f[v]=u;dfs(v);
     57         dp[u][0]+=max(dp[v][0],dp[v][1]);
     58         dp[u][1]+=dp[v][0];        
     59     }
     60     si[u].p[0][0]=si[u].p[0][1]=dp[u][0];
     61     si[u].p[1][0]=dp[u][1];
     62     s[u]=si[u];//开始s和si都一样 
     63 }
     64 
     65 I void pushup(R int x)
     66 {
     67     s[x]=si[x];//考虑推出的矩阵式子,其实就是
     68     //虚子树*dep小于dep[x]的和dep>dep[x]的实链上的,就是整棵树的贡献 
     69     if(ls(x))s[x]=s[ls(x)]*s[x];
     70     if(rs(x))s[x]=s[x]*s[rs(x)];
     71 }
     72 //一下为LCT板子,不需要link也不要cut也不要makeroot 
     73 I bool nroot(int x)
     74 {
     75     return ls(f[x])==x||rs(f[x])==x;
     76 }
     77 
     78 I void rotate(R int x)
     79 {
     80     int y=f[x],z=f[y],k=(rs(y)==x),w=ch[x][!k];
     81     if(nroot(y))ch[z][rs(z)==y]=x;ch[x][!k]=y;ch[y][k]=w;
     82     if(w)f[w]=y;f[x]=z;f[y]=x;pushup(y);pushup(x);
     83 }
     84 
     85 I void splay(R int x)
     86 {
     87     while(nroot(x))
     88     {
     89         int y=f[x],z=f[y];
     90         if(nroot(y))rotate((ls(y)==x)^(ls(z)==y)?x:y);
     91         rotate(x);
     92     }
     93 }    
     94 //这其实就是维护虚子树信息的access写法 
     95 I void access(R int x)
     96 {
     97     for(int y=0;x;x=f[y=x])
     98     {
     99         splay(x);
    100         if(rs(x))//实变虚,加到虚树中 
    101         {
    102             si[x].p[0][0]+=max(s[rs(x)].p[0][0],s[rs(x)].p[1][0]);
    103             si[x].p[1][0]+=s[rs(x)].p[0][0];
    104         }
    105         rs(x)=y;
    106         if(rs(x))//虚变实,从虚树中减去 
    107         {
    108             si[x].p[0][0]-=max(s[rs(x)].p[0][0],s[rs(x)].p[1][0]);
    109             si[x].p[1][0]-=s[rs(x)].p[0][0];
    110         }si[x].p[0][1]=si[x].p[0][0];
    111         pushup(x);//别忘了更新 
    112     }
    113 }
    114 
    115 I void modify(int x,int y)//很显然的修改函数 
    116 {
    117     access(x);splay(x);
    118     si[x].p[1][0]-=a[x]-y;//转到splay的根上,照着dp方程直接修改即可 
    119     a[x]=y;pushup(x);
    120 }
    121 
    122 I void addedge(int u,int v)
    123 {
    124     g[++cnt].nxt=head[u];
    125     g[cnt].to=v;head[u]=cnt;
    126 }
    127 
    128 int main()
    129 {
    130     n=read();m=read();
    131     for(int i=1;i<=n;i++)a[i]=read();
    132     for(int i=1;i<n;i++)
    133     {
    134         int x=read(),y=read();
    135         addedge(x,y);addedge(y,x);
    136     }
    137     dfs(1);
    138     while(m--)
    139     {
    140         int x=read(),y=read();
    141         modify(x,y);splay(1);//选一个点为根输出答案 
    142         printf("%lld
    ",max(s[1].p[0][0],s[1].p[1][0]));
    143     }
    144 }
    show you the code

    线性求逆元

    (记住就行了,从$p=k*i+r≡0(mod p)$开始推,乘一个$i^{-1}$和$r^{-1}$即可

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 using namespace std;
     5 const int N=3e6+10;
     6 I int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    11     return x*f;
    12 }
    13 int n;
    14 int p,inv[N];
    15 
    16 int main()
    17 {
    18     n=read();p=read();
    19     inv[1]=1;
    20     for(int i=2;i<=n;i++)
    21     inv[i]=1LL*(p-p/i)*(inv[p%i])%p;
    22     for(int i=1;i<=n;i++)printf("%d
    ",inv[i]);
    23 }
    show you the code

    康拓展开

    (就是给你一个$1-n$的排列,问你按字典序是$1-n$全排列的第几个(注意是否从$0$开始计算)$ans=(1+)sumlimits_{i=1}^na_i*(n-i)!$ 

     1 #include<bits/stdc++.h>
     2 #define lowbit(x) (x&-x)
     3 #define I inline
     4 using namespace std;
     5 using namespace std;
     6 const int N=1000010;
     7 const int p=998244353;
     8 I int read()
     9 {
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int n,a[N],ans;
    16 int bit[N],fac[N];
    17 
    18 I void add(int pos,int val)
    19 {
    20     while(pos<=n)bit[pos]+=val,pos+=lowbit(pos);
    21 }
    22 I int query(int pos)
    23 {
    24     int res=0;
    25     while(pos)res+=bit[pos],pos-=lowbit(pos);
    26     return res;
    27 }
    28 
    29 int main()
    30 {
    31     n=read();for(int i=1;i<=n;i++)a[i]=read();
    32     fac[0]=1;
    33     for(int i=1;i<=n;i++)add(i,1),fac[i]=1LL*i*fac[i-1]%p;
    34     for(int i=1;i<=n;i++)
    35     {
    36         int k=query(a[i])-1;
    37         ans=(ans+1LL*k*fac[n-i]%p)%p;
    38         add(a[i],-1);
    39     }
    40     cout<<ans+1;
    41 }
    show you the code

     线段树1

    没啥可说的

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 using namespace std;
      5 #define smid ((l+r)>>1)
      6 #define lch (now<<1)
      7 #define rch ((now<<1)|1)
      8 #define maxn 100005
      9 #define maxlen maxn*4
     10 #define root 1
     11 struct Sgt
     12 {long long num,pls;}sgt[maxlen];
     13 int n,m;
     14 long long a[maxn];
     15 void update(int now)
     16 {
     17     sgt[now].num=sgt[lch].num+sgt[rch].num;
     18 }
     19 void pushdown(int now,int l,int r)
     20 {
     21     if(sgt[now].pls)
     22     {
     23         sgt[lch].pls+=sgt[now].pls;
     24         sgt[lch].num+=(smid-l+1)*sgt[now].pls;
     25         sgt[rch].num+=(r-(smid+1)+1)*sgt[now].pls;
     26         sgt[rch].pls+=sgt[now].pls;
     27         sgt[now].pls=0;
     28     }
     29 }
     30 void build_sgt(int now,int l,int r)
     31 {
     32     if(l==r)
     33     {
     34         sgt[now].num=a[l];return ;
     35         }
     36         build_sgt(lch,l,smid);
     37         build_sgt(rch,smid+1,r);
     38         update(now);
     39     }
     40 void plus_sgt(int now,int l,int r,int x,int y,long long  val)
     41 {
     42     if(l==x&&r==y)
     43     {
     44         sgt[now].num+=(y-x+1)*val;
     45         sgt[now].pls+=val;
     46         return ;
     47     }
     48     pushdown(now,l,r);
     49     if(y<=smid)
     50     {
     51         plus_sgt(lch,l,smid,x,y,val);
     52     }
     53     else if(x>smid)
     54     {
     55         plus_sgt(rch,smid+1,r,x,y,val);
     56     }
     57     else
     58     {
     59         plus_sgt(lch,l,smid,x,smid,val);
     60         plus_sgt(rch,smid+1,r,smid+1,y,val);
     61     }
     62     update(now);
     63 }
     64 long long qry_sgt(int now,int l,int r,int x,int y)
     65 {
     66     if(l==x&&r==y)
     67     {
     68         return sgt[now].num;
     69     }
     70     pushdown(now,l,r);
     71     if(y<=smid)
     72     return qry_sgt(lch,l,smid,x,y);
     73     else if(x>smid)
     74     return qry_sgt(rch,smid+1,r,x,y);
     75     else
     76     return qry_sgt(lch,l,smid,x,smid)+qry_sgt(rch,smid+1,r,smid+1,y);
     77 }
     78 int main()
     79 {
     80     cin>>n>>m;
     81     for(int i=1;i<=n;i++)
     82     {
     83         scanf("%lld",&a[i]);
     84         }
     85         build_sgt(root,1,n);
     86         for(int i=1;i<=m;i++)
     87         {
     88             int cid;
     89             scanf("%d",&cid);
     90             if(cid==1)
     91             {
     92                 int x,y;
     93                 long long k;
     94                 scanf("%d%d%lld",&x,&y,&k);
     95                 plus_sgt(root,1,n,x,y,k);
     96             }    
     97             if(cid==2)
     98             {
     99                 int x,y;
    100                 scanf("%d%d",&x,&y);
    101                 printf("%lld
    ",qry_sgt(root,1,n,x,y));
    102             }
    103         }
    104     }
    show you the code

    线段树2

    注意下放标记的顺序即可,当然线段树的板子不止于此

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define root 1
    #define lch now*2
    #define rch now*2+1
    #define smid (l+r)/2
    using namespace std;
    typedef long long LL;
    const int maxn=100005;
    
    int n,m,p;
    struct node
    {
        LL pls,mul,sum;
    }sgt[maxn*4];
    LL a[maxn];
    
    void update(int now)
    {
        sgt[now].sum=(sgt[lch].sum+sgt[rch].sum)%p;
    }
    
    void pushdown(int now,int l,int r)
    {
        sgt[lch].pls=(sgt[lch].pls*sgt[now].mul%p+sgt[now].pls)%p;
        sgt[rch].pls=(sgt[rch].pls*sgt[now].mul%p+sgt[now].pls)%p;
        sgt[lch].mul=(sgt[lch].mul*sgt[now].mul)%p;
        sgt[rch].mul=(sgt[rch].mul*sgt[now].mul)%p;
        sgt[lch].sum=(sgt[now].pls*(smid-l+1)%p+sgt[lch].sum*sgt[now].mul%p)%p;
        sgt[rch].sum=(sgt[now].pls*(r-smid)%p+sgt[rch].sum*sgt[now].mul%p)%p;
        sgt[now].pls=0;
        sgt[now].mul=1;
    }
    
    void build_sgt(int now,int l,int r)
    {
        sgt[now].pls=0;
        sgt[now].mul=1;
        if(l==r)
        {
            sgt[now].sum=a[l];
            return;
        }
        build_sgt(lch,l,smid);
        build_sgt(rch,smid+1,r);
        update(now);
    }
    
    void plus_sgt(int now,int l,int r,int x,int y,LL val)
    {
        
        if(l==x&&r==y)
        {
            sgt[now].pls=(sgt[now].pls+val)%p;
            sgt[now].sum=(sgt[now].sum+(r-l+1)%p*val%p)%p;
            return;
        }
        pushdown(now,l,r);
        if(y<=smid)
        plus_sgt(lch,l,smid,x,y,val);
        else if(x>smid)
        plus_sgt(rch,smid+1,r,x,y,val);
        else
        {
            plus_sgt(lch,l,smid,x,smid,val);
            plus_sgt(rch,smid+1,r,smid+1,y,val);
        }
        update(now);
    }
    
    void multipy_sgt(int now,int l,int r,int x,int y,LL val)
    {
        if(l==x&&r==y)
        {
            sgt[now].sum=sgt[now].sum*val%p;
            sgt[now].mul=sgt[now].mul*val%p;
            sgt[now].pls=sgt[now].pls*val%p;
            return;
        }
        pushdown(now,l,r);
        if(y<=smid)
        multipy_sgt(lch,l,smid,x,y,val);
        else if(x>smid)
        multipy_sgt(rch,smid+1,r,x,y,val);
        else
        {
            multipy_sgt(lch,l,smid,x,smid,val);
            multipy_sgt(rch,smid+1,r,smid+1,y,val);
        }
        update(now);
    }
    
    LL query_sgt(int now,int l,int r,int x,int y)
    {
        if(x==l&&r==y)
        return sgt[now].sum;
        pushdown(now,l,r);
        if(y<=smid)
        return query_sgt(lch,l,smid,x,y)%p;
        else if(x>smid)
        return query_sgt(rch,smid+1,r,x,y)%p;
        else
        {
            return (query_sgt(lch,l,smid,x,smid)%p+
            query_sgt(rch,smid+1,r,smid+1,y)%p)%p;
        }
    }
        
    int main()
    {
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        build_sgt(root,1,n);
        while(m--)
        {
            int cid;
            scanf("%d",&cid);
            if(cid==1)
            {
                int x,y;
                LL k;
                scanf("%d%d%lld",&x,&y,&k);
                multipy_sgt(root,1,n,x,y,k);
            }
            if(cid==2)
            {
                int x,y;
                LL k;
                scanf("%d%d%lld",&x,&y,&k);
                plus_sgt(root,1,n,x,y,k);
            }
            if(cid==3)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%lld
    ",query_sgt(root,1,n,x,y)%p);
            }
        }
    }
    show you the code

    2-SAT

    加边的时候多注意就行,至于构造方案,,,考的不多,主要是不太理解为什么取拓扑序大的就行了

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=2000010;
     5 I int read()
     6 {
     7     int x=0,f=1;char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    10     return x*f;
    11 }
    12 vector<int>g[N];
    13 int n,m;
    14 I void add(int u,int v){g[u].push_back(v);}
    15 int dfn[N],low[N],sta[N],col[N],color,ind,top;
    16 
    17 I void tarjan(int u)
    18 {
    19     low[u]=dfn[u]=++ind;sta[++top]=u;
    20     for(int i=0;i<g[u].size();i++)
    21     {
    22         int v=g[u][i];
    23         if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
    24         else if(!col[v])low[u]=min(low[u],dfn[v]);
    25     }
    26     if(low[u]==dfn[u])
    27     {
    28         color++;
    29         while(sta[top]!=u)
    30         {
    31             col[sta[top]]=color;
    32             top--;
    33         }top--;col[u]=color;        
    34     }
    35 }
    36 
    37 I bool chk()
    38 {
    39     for(int i=1;i<=n;i++)
    40     if(col[i]==col[i+n])return 0;
    41     return 1;
    42 }
    43 
    44 int main()
    45 {
    46     n=read();m=read();
    47     for(int i=1;i<=m;i++)
    48     {
    49         int a=read(),b=read(),c=read(),d=read();
    50         if(b&&d)add(a,c+n),add(c,a+n);
    51         if(!b&&d)add(a+n,c+n),add(c,a);
    52         if(b&&!d)add(a,c),add(c+n,a+n);
    53         if(!b&&!d)add(a+n,c),add(c+n,a);
    54     }
    55     for(int i=1;i<=(n<<1);i++)if(!dfn[i])tarjan(i);
    56     if(chk())
    57     {
    58         puts("POSSIBLE");
    59         for(int i=1;i<=n;i++)
    60         {
    61             printf("%d ",col[i]>col[i+n]);
    62         }
    63         return 0;
    64     }
    65     cout<<"IMPOSSIBLE";
    66     return 0;
    67 }
    show you the code

     三分

    求单峰函数极值

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const double eps=1e-8;
     4 int n;
     5 double a[20],l,r;
     6 
     7 double val(double x)
     8 {
     9     double res=0;int v=0;
    10     for(int i=n+1;i>=1;i--)res+=a[++v]*pow(x,i-1);
    11     return res;
    12 }
    13 
    14 int main()
    15 {
    16     cin>>n>>l>>r;
    17     for(int i=1;i<=n+1;i++)cin>>a[i];
    18     while(r-l>eps)
    19     {
    20         double m1=l+(r-l)/3.0,m2=r-(r-l)/3.0;
    21         if(val(m1)-val(m2)>eps)r=m2;
    22         else l=m1;
    23     }
    24     printf("%.5lf",l);
    25 }
    show you the code

     割点

    判断$low[v]>=dfn[u]$

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=20010;
     5 const int M=100010;
     6 I int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    11     return x*f;
    12 }
    13 
    14 int n,m;
    15 vector<int>g[N];
    16 bool cut[N];
    17 int ans;
    18 int dfn[N],low[N],ind;
    19 
    20 I void tarjan(int u,int rt)
    21 {
    22     int ch=0;
    23     low[u]=dfn[u]=++ind;
    24     for(int i=0;i<g[u].size();i++)
    25     {
    26         int v=g[u][i];
    27         if(!dfn[v])
    28         {
    29             tarjan(v,rt);
    30             low[u]=min(low[u],low[v]);
    31             if(u!=rt&&low[v]>=dfn[u])cut[u]=1;
    32             if(u==rt)ch++;
    33         }
    34         low[u]=min(low[u],dfn[v]);
    35     }
    36     if(ch>=2&&u==rt)cut[u]=1;
    37 }
    38     
    39 int main()
    40 {
    41     n=read();m=read();
    42     for(int i=1;i<=m;i++)
    43     {
    44         int x=read(),y=read();
    45         g[x].push_back(y);
    46         g[y].push_back(x);
    47     }
    48     for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i,i);    
    49     for(int i=1;i<=n;i++)if(cut[i])ans++;
    50     cout<<ans<<endl;
    51     for(int i=1;i<=n;i++)if(cut[i])printf("%d ",i);
    52 }
    show you the code

    树链剖分

     挑战30min打出树剖板子成功

      1 #include<bits/stdc++.h>
      2 #define I inline
      3 #define ls (now<<1)
      4 #define rs (now<<1|1)
      5 #define smid (l+r>>1)
      6 using namespace std;
      7 const int N=1e5+10;
      8 I int read()
      9 {
     10     int x=0,f=1;char ch=getchar();
     11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     13     return x*f;
     14 }
     15 struct segment
     16 {
     17     int sum,pls;
     18 }sgt[N<<2];
     19 int n,m,rt,p;
     20 vector<int>g[N];
     21 int a[N];
     22 int dep[N],f[N],rk[N],id[N],ind,top[N],son[N],sz[N];
     23 
     24 I void dfs1(int u)
     25 {
     26     dep[u]=dep[f[u]]+1;
     27     sz[u]=1;
     28     for(int i=0;i<g[u].size();i++)
     29     {
     30         int v=g[u][i];
     31         if(v==f[u])continue;
     32         f[v]=u;dfs1(v);
     33         sz[u]+=sz[v];
     34         if(sz[v]>sz[son[u]])son[u]=v;
     35     }
     36 }
     37 
     38 I void dfs2(int u,int tp)
     39 {
     40     top[u]=tp;
     41     rk[++ind]=u;
     42     id[u]=ind;
     43     if(son[u])dfs2(son[u],tp);
     44     for(int i=0;i<g[u].size();i++)
     45     {
     46         int v=g[u][i];
     47         if(v==f[u]||v==son[u])continue;
     48         dfs2(v,v);
     49     }
     50 }
     51 
     52 I void pushup(int now)
     53 {
     54     sgt[now].sum=sgt[ls].sum+sgt[rs].sum;
     55 }
     56 
     57 I void pushdown(int now,int l,int r)
     58 {
     59     if(!sgt[now].pls)return;
     60     sgt[ls].pls=(sgt[ls].pls+sgt[now].pls)%p;
     61     sgt[rs].pls=(sgt[rs].pls+sgt[now].pls)%p;
     62     sgt[ls].sum=(sgt[ls].sum+1LL*(smid-l+1)*sgt[now].pls%p)%p;
     63     sgt[rs].sum=(sgt[rs].sum+1LL*(r-smid)*sgt[now].pls%p)%p;
     64     sgt[now].pls=0;
     65 }
     66 
     67 I void bt(int now,int l,int r)
     68 {
     69     if(l==r){sgt[now].sum=a[rk[l]];return ;}
     70     bt(ls,l,smid);bt(rs,smid+1,r);
     71     pushup(now);
     72 }
     73 
     74 I void modify(int now,int l,int r,int x,int y,int k)
     75 {
     76     if(x<=l&&r<=y)
     77     {
     78         sgt[now].sum=(sgt[now].sum+1LL*(r-l+1)*k%p)%p;
     79         sgt[now].pls=(sgt[now].pls+k)%p;
     80         return ;
     81     }
     82     pushdown(now,l,r);
     83     if(x<=smid)modify(ls,l,smid,x,y,k);
     84     if(smid<y)modify(rs,smid+1,r,x,y,k);
     85     pushup(now);
     86 }
     87 
     88 I int query(int now,int l,int r,int x,int y)
     89 {
     90     if(x<=l&&r<=y)return sgt[now].sum;
     91     pushdown(now,l,r);
     92     int res=0;
     93     if(x<=smid)res=(res+query(ls,l,smid,x,y))%p;
     94     if(smid<y)res=(res+query(rs,smid+1,r,x,y))%p;
     95     return res;
     96 }
     97 
     98 I void change_range(int x,int y,int z)
     99 {
    100     while(top[x]!=top[y])
    101     {
    102         if(dep[top[x]]<dep[top[y]])swap(x,y);
    103         modify(1,1,n,id[top[x]],id[x],z);
    104         x=f[top[x]];
    105     }
    106     if(dep[x]<dep[y])swap(x,y);
    107     modify(1,1,n,id[y],id[x],z);
    108 }
    109 
    110 I int query_range(int x,int y)
    111 {
    112     int res=0;
    113     while(top[x]!=top[y])
    114     {
    115         if(dep[top[x]]<dep[top[y]])swap(x,y);
    116         res=(res+query(1,1,n,id[top[x]],id[x]))%p;
    117         x=f[top[x]];
    118     }
    119     if(dep[x]<dep[y])swap(x,y);
    120     res=(res+query(1,1,n,id[y],id[x]))%p;
    121     return res;
    122 }
    123 
    124 I void change_tree(int x,int z)
    125 {
    126     modify(1,1,n,id[x],id[x]+sz[x]-1,z);
    127 }
    128 
    129 I int query_tree(int x)
    130 {
    131     return query(1,1,n,id[x],id[x]+sz[x]-1);
    132 }
    133 
    134 int main()
    135 {
    136     n=read();m=read();rt=read();p=read();
    137     for(int i=1;i<=n;i++)a[i]=read();
    138     for(int i=1;i<n;i++)
    139     {
    140         int x=read(),y=read();
    141         g[x].push_back(y);
    142         g[y].push_back(x);
    143     }
    144     dfs1(rt);
    145     dfs2(rt,rt);
    146     bt(1,1,n);
    147     while(m--)
    148     {
    149         int cid=read();
    150         if(cid==1)
    151         {
    152             int x=read(),y=read(),z=read();
    153             change_range(x,y,z);
    154         }
    155         if(cid==2)
    156         {
    157             int x=read(),y=read();
    158             printf("%d
    ",query_range(x,y)%p);
    159         }
    160         if(cid==3)
    161         {
    162             int x=read(),z=read();
    163             change_tree(x,z);
    164         }
    165         if(cid==4)
    166         {
    167             int x=read();
    168             printf("%d
    ",query_tree(x))%p;
    169         }
    170     }
    171 }
    show you the code

     树状数组1

    没啥可说的

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 #define lowbit(pos) ((pos)&(-pos))
     6 #define maxn 500005
     7 int tarr[maxn];
     8 int n,m;
     9 void addtarr(int pos,int k)
    10 {
    11     while(pos<maxn)
    12     {
    13         tarr[pos]+=k;
    14         pos+=lowbit(pos);
    15     }
    16 }
    17 int qrytarr(int pos)
    18 {
    19     int res=0;
    20     while(pos)
    21     {
    22         res+=tarr[pos];
    23         pos-=lowbit(pos);
    24     }
    25     return res;
    26 }
    27 int main()
    28 {
    29     scanf("%d%d",&n,&m);
    30     for(int i=1;i<=n;i++)
    31     {int p;scanf("%d",&p);addtarr(i,p);}
    32     for(int i=1;i<=m;i++)
    33     {
    34         int cid;
    35         int x;
    36         scanf("%d",&cid);
    37         if(cid==1)
    38         {
    39             int x,k;
    40             scanf("%d%d",&x,&k);
    41             addtarr(x,k);
    42         }
    43         else
    44         {
    45             int j,y;
    46             scanf("%d%d",&j,&y);
    47             printf("%d
    ",qrytarr(y)-qrytarr(j-1));
    48         }
    49     }
    50 }
    show you the code

    树状数组2

    差分一下就行了

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 using namespace std;
     5 #define maxn 500005
     6 #define lowbit(x) (x)&(-x)
     7 int tarr[maxn];
     8 int n,m;
     9 int in[maxn];
    10 void addtarr(int pos,int v)
    11 {
    12     while(pos<=maxn)
    13     {
    14         tarr[pos]+=v;
    15         pos+=lowbit(pos);}
    16     }
    17     int qrytarr(int pos)
    18     {
    19         int res=0;
    20         while(pos)
    21     {
    22         res+=tarr[pos];
    23         pos-=lowbit(pos);}
    24         return res;
    25     }
    26 int main()
    27 {
    28     scanf("%d%d",&n,&m);
    29     for(int i=1;i<=n;i++)
    30     {
    31         int x;
    32         scanf("%d",&in[i]);}
    33         for(int i=1;i<=n;i++)
    34         {addtarr(i,in[i]-in[i-1]);}
    35         //for(int s=1;s<=n;s++)
    36         //{cout<<tarr[s]<<" ";}
    37         //cout<<endl;
    38         for(int i=1;i<=m;i++)
    39         {
    40             int cid;
    41             scanf("%d",&cid);
    42             if(cid==1)
    43             {int x,y,k;
    44             scanf("%d%d%d",&x,&y,&k);
    45             addtarr(x,k);
    46             addtarr(y+1,-k);
    47         }
    48         if(cid==2)
    49         {
    50             int x;
    51             scanf("%d",&x);
    52             printf("%d
    ",qrytarr(x));
    53         }
    54     }
    55 }            
    show you the code

    普通平衡树(fhq Treap)

    记得画图模拟split和merge,merge时按照rank,split时按照val

      1 #include<bits/stdc++.h>
      2 #define ls(x) ch[x][0]
      3 #define rs(x) ch[x][1]
      4 #define I inline
      5 using namespace std;
      6 const int N=100010;
      7 I int read()
      8 {
      9     int x=0,f=1;char ch=getchar();
     10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
     12     return x*f;
     13 }
     14 
     15 int ch[N][2],rnk[N],val[N],sz[N],root,x,y,z,cnt;
     16 int n;
     17 
     18 I void pushup(int now)
     19 {
     20     sz[now]=sz[ls(now)]+sz[rs(now)]+1;
     21 }
     22 
     23 I void split(int now,int k,int &x,int &y)
     24 {
     25     if(!now)x=y=0;
     26     else 
     27     {
     28         if(val[now]<=k)x=now,split(rs(now),k,rs(now),y);
     29         else y=now,split(ls(now),k,x,ls(now));
     30         pushup(now);
     31     }
     32 }
     33 
     34 I int merge(int x,int y)
     35 {
     36     if(!x||!y)return x+y;
     37     if(rnk[x]<rnk[y]){rs(x)=merge(rs(x),y);pushup(x);return x;}
     38     else{ls(y)=merge(x,ls(y));pushup(y);return y;}
     39 }
     40 
     41 I int kth(int now,int k)
     42 {
     43     while(1)
     44     {
     45         if(k<=sz[ls(now)])now=ls(now);
     46         else if(k==sz[ls(now)]+1)return now;
     47         else k-=sz[ls(now)]+1,now=rs(now);
     48     }
     49 }
     50 
     51 I int new_node(int x)
     52 {
     53     cnt++;sz[cnt]=1;
     54     val[cnt]=x;rnk[cnt]=rand();
     55     return cnt;
     56 }
     57 
     58 I void insert(int k)
     59 {
     60     split(root,k,x,y);
     61     root=merge(merge(x,new_node(k)),y);
     62 }
     63 
     64 I void del(int k)
     65 {
     66     split(root,k,x,z);
     67     split(x,k-1,x,y);
     68     y=merge(ls(y),rs(y));
     69     root=merge(merge(x,y),z);
     70 }
     71 
     72 I int getrank(int k)
     73 {
     74     split(root,k-1,x,y);
     75     printf("%d
    ",sz[x]+1); 
     76     root=merge(x,y);
     77 }
     78 
     79 I int get_pre(int k)
     80 {
     81     split(root,k-1,x,y);
     82     printf("%d
    ",val[kth(x,sz[x])]);
     83     root=merge(x,y);
     84 }
     85 
     86 I int get_nxt(int k)
     87 {
     88     split(root,k,x,y);
     89     printf("%d
    ",val[kth(y,1)]);
     90     root=merge(x,y);
     91 }
     92 
     93 int main()
     94 {
     95     srand(time(0));
     96     n=read();
     97     while(n--)
     98     {
     99         int op=read(),k=read();
    100         if(op==1)insert(k);
    101         if(op==2)del(k);
    102         if(op==3)getrank(k);
    103         if(op==4)printf("%d
    ",val[kth(root,k)]);
    104         if(op==5)get_pre(k);
    105         if(op==6)get_nxt(k);
    106     }
    107 }
    show you the code

    矩阵快速幂

    记得精度,重载比较美观,记得单位矩阵

     1 #include<bits/stdc++.h>
     2 #define ls(x) ch[x][0]
     3 #define rs(x) ch[x][1]
     4 #define I inline
     5 using namespace std;
     6 const int N=110;
     7 const int p=1e9+7;
     8 typedef long long LL;
     9 struct mat
    10 {
    11     LL p[N][N];
    12 }base,ans,a;
    13 
    14 int n;
    15 LL k;
    16 
    17 mat operator * (mat a,mat b)
    18 {
    19     mat c;
    20     for(int i=1;i<=n;i++)
    21     for(int j=1;j<=n;j++)
    22     c.p[i][j]=0;
    23     
    24     for(int i=1;i<=n;i++)
    25     for(int k=1;k<=n;k++)
    26     for(int j=1;j<=n;j++)
    27     c.p[i][j]=(c.p[i][j]%p+a.p[i][k]*b.p[k][j]%p)%p;
    28     return c;
    29 }
    30 
    31 mat qpow(mat a,LL k)
    32 {
    33     for(int i=1;i<=n;i++)base.p[i][i]=1;
    34     while(k)
    35     {
    36         if(k&1LL)base=base*a;
    37         a=a*a;k>>=1LL;
    38     }
    39     return base;
    40 }
    41 
    42 int main()
    43 {
    44     cin>>n>>k;
    45     for(int i=1;i<=n;i++)
    46     for(int j=1;j<=n;j++)
    47     cin>>a.p[i][j];
    48     ans=qpow(a,k);
    49     for(int i=1;i<=n;i++)
    50     {
    51         for(int j=1;j<=n;j++)
    52         printf("%lld ",ans.p[i][j]%p);
    53         printf("
    ");
    54     }
    55 }
    show you the code

     卢卡斯定理

    模数p小的情况下用于求组合数。

    公式 $C_m^n=C_{m/p}^{n/p}*C_{mmod p}^{nmod p}$

    模运算直接算,除法运算递归即可。

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=1e5+10;
     5 I int read()
     6 {
     7     int x=0,f=1;char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    10     return x*f;
    11 }
    12 int T,fac[N];
    13 
    14 I int ksm(int a,int b,int p)
    15 {
    16     int res=1;
    17     while(b)
    18     {
    19         if(b&1)res=1LL*res*a%p;
    20         a=1LL*a*a%p;
    21         b>>=1;
    22     }
    23     return res;
    24 }
    25 
    26 I int C(int n,int m,int p)
    27 {
    28     if(n<m)return 0;
    29     return 1LL*fac[n]*ksm(fac[m],p-2,p)%p*1LL*ksm(fac[n-m],p-2,p)%p;
    30 }
    31 
    32 I int Lucas(int n,int m,int p)
    33 {
    34     return !m?1:1LL*C(n%p,m%p,p)*Lucas(n/p,m/p,p)%p;
    35 }
    36 
    37 int main()
    38 {
    39     T=read();
    40     while(T--)
    41     {
    42         int n=read(),m=read(),p=read();
    43         fac[0]=1;for(int i=1;i<=p;i++)fac[i]=1LL*fac[i-1]*i%p;
    44         printf("%d
    ",Lucas(n+m,m,p));
    45     }
    46 }
    show you the code

     线性筛素数

    背掉,关键在于$imod prime[j]=0$时$i*prime[j]$可以被一个更小的质数和一个更大的合数表示

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=10000010;
     5 int prime[N],cnt;
     6 bool not_prime[N];
     7 int n,m;
     8 
     9 I void pre()
    10 {
    11     not_prime[0]=not_prime[1]=1;
    12     for(int i=2;i<=n;i++)
    13     {
    14         if(!not_prime[i])prime[++cnt]=i;
    15         for(int j=1;j<=cnt&&prime[j]*i<=n;j++)
    16         {
    17             not_prime[prime[j]*i]=1;
    18             if(i%prime[j]==0)break;
    19         }
    20     }
    21 }
    22 int main()
    23 {
    24     cin>>n>>m;
    25     pre();
    26     while(m--)
    27     {
    28         int x;scanf("%d",&x);
    29         if(not_prime[x])puts("No");
    30         else puts("Yes");
    31     }
    32 }
    show you the code

     矩阵加速递推

    注意细节,可以用初始矩阵开始乘,也可以用单位矩阵开始乘

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 typedef long long LL;
     5 const int p=1e9+7;
     6 I int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    11     return x*f;
    12 }
    13 struct mat
    14 {
    15     LL p[5][5];
    16 }base,ans;
    17 int T;
    18 
    19 I mat operator * (mat a,mat b)
    20 {
    21     mat c;memset(c.p,0,sizeof(c.p));
    22     for(int i=1;i<=3;i++)
    23     for(int k=1;k<=3;k++)
    24     for(int j=1;j<=3;j++)
    25     c.p[i][j]=(c.p[i][j]%p+a.p[i][k]*b.p[k][j]%p)%p;
    26     return c;
    27 }
    28 
    29 void mat_ksm(int k)
    30 {
    31     memset(base.p,0,sizeof(base.p));
    32     memset(ans.p,0,sizeof(ans.p));
    33     base.p[1][1]=base.p[2][1]=base.p[1][3]=base.p[3][2]=1;
    34     ans.p[1][1]=ans.p[2][1]=ans.p[3][1]=1;
    35     while(k)
    36     {
    37         if(k&1)ans=ans*base;
    38         base=base*base;
    39         k>>=1;
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     T=read();
    46     while(T--)
    47     {
    48         int n=read();
    49         if(n<=3)puts("1");
    50         else
    51         {
    52             mat_ksm(n-1);
    53             printf("%lld
    ",ans.p[1][1]);
    54         }
    55     }
    56 }
    show you the code

    有理数取余(大数除法模运算)

    $$cequivfrac{a}{b}pmod p$$

    $$b*cequiv apmod p$$

    $$b*(a*inv[b])equiv apmod p$$

    $$b_{mod p}*a_{mod p}*inv[b]_{mod p}equiv a_{mod p}pmod p$$

    $$c=a_{mod p}*inv[b]_{mod p}$$

    求一下逆元就好了,这里因为有angry的情况,根据exgcd的成立条件特判即可。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #define LL long long
     6 using namespace std;
     7 const LL p=19260817;
     8 LL a,b;
     9 LL x,y;
    10 inline LL read()
    11 {
    12     LL x=0,f=1;
    13     char ch=getchar();
    14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0'&&ch<='9')
    16     {
    17         x=(x*10%p+(ch-'0')%p)%p;ch=getchar();
    18     }
    19     return (x*f)%p;
    20 }
    21 LL exgcd(LL a,LL b,LL &x,LL &y)
    22 {
    23     if(b==0)
    24     {
    25         x=1;y=0;
    26         return a;
    27     }
    28     LL k=exgcd(b,a%b,x,y);
    29     LL t=x;
    30     x=y;
    31     y=t-(a/b)*y;
    32     return k;
    33 }
    34 int main()
    35 {
    36     a=read();
    37     b=read();
    38     LL r=exgcd(b,p,x,y);
    39     if(r!=1){cout<<"Angry!";return 0;}
    40     x=(x%p+p)%p;
    41     cout<<(x%p*a%p)%p;
    42     return 0;
    43 }
    show you the code

    二分图匹配

    注意判vis,找当前点增光路的时候如果有环(之前被dfs的点又被找了一次)直接跳过

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=1010;
     5 I int read()
     6 {
     7     int x=0,f=1;char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    10     return x*f;
    11 }
    12 int g[N][N];
    13 int n,m,e;
    14 int ans,match[N];
    15 bool vis[N];
    16 
    17 I bool dfs(int u)
    18 {
    19     for(int v=1;v<=m;v++)
    20     {
    21         if(!vis[v]&&g[u][v])
    22         {
    23             vis[v]=1;
    24             if(!match[v]||dfs(match[v]))
    25             {
    26                 match[v]=u;return 1;
    27             }
    28         }
    29     }return 0;
    30 }
    31 
    32 int main()
    33 {
    34     n=read();m=read();e=read();
    35     for(int i=1;i<=e;i++)
    36     {
    37         int x=read(),y=read();
    38         if(x<=n&&y<=m)g[x][y]=1;
    39     }
    40     for(int i=1;i<=n;i++)
    41     {
    42         memset(vis,0,sizeof(vis));
    43         ans+=dfs(i);
    44     }
    45     cout<<ans;
    46 }
    show you the code

    树上公共祖先(树剖求LCA)

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=500010;
     5 I int read()
     6 {
     7     int x=0,f=1;char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    10     return x*f;
    11 }
    12 vector<int>g[N];
    13 int n,m,rt;
    14 int dep[N],son[N],sz[N],top[N],f[N];
    15 
    16 I void dfs1(int u)
    17 {
    18     dep[u]=dep[f[u]]+1;
    19     sz[u]=1;
    20     for(int i=0;i<g[u].size();i++)
    21     {
    22         int v=g[u][i];
    23         if(v==f[u])continue;
    24         f[v]=u;dfs1(v);
    25         sz[u]+=sz[v];
    26         if(sz[v]>sz[son[u]])son[u]=v;
    27     }
    28 }
    29 
    30 I void dfs2(int u,int tp)
    31 {
    32     top[u]=tp;if(son[u])dfs2(son[u],tp);
    33     for(int i=0;i<g[u].size();i++)
    34     {
    35         int v=g[u][i];
    36         if(v==f[u]||v==son[u])continue;
    37         dfs2(v,v);
    38     }
    39 }
    40 
    41 I int LCA(int x,int y)
    42 {
    43     while(top[x]!=top[y])
    44     {
    45         if(dep[top[x]]<dep[top[y]])swap(x,y);
    46         x=f[top[x]];
    47     }
    48     if(dep[x]<dep[y])swap(x,y);
    49     return y;
    50 }
    51 
    52 
    53 int main()
    54 {
    55     n=read();m=read();rt=read();
    56     for(int i=1;i<n;i++)
    57     {
    58         int x=read(),y=read();
    59         g[x].push_back(y);
    60         g[y].push_back(x);
    61     }
    62     dfs1(rt);dfs2(rt,rt);
    63     while(m--)
    64     {
    65         int x=read(),y=read();
    66         printf("%d
    ",LCA(x,y));
    67     }
    68 }
    show you the code

     快速幂

    不说什么。。。

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 I int read()
     5 {
     6     int x=0,f=1;char ch=getchar();
     7     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     8     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     9     return x*f;
    10 }
    11 int b,k,p;
    12 
    13 I int ksm(int b,int k,int p)
    14 {
    15     int res=1;
    16     while(k)
    17     {
    18         if(k&1)res=1LL*res*b%p;
    19         b=1LL*b*b%p;k>>=1;
    20     }
    21     return res%p;
    22 }
    23 
    24 int main()
    25 {
    26     b=read();k=read();p=read();
    27     printf("%d^%d mod %d=%d",b,k,p,ksm(b,k,p));
    28 }
    show you the code

    字符串匹配(KMP)

    注意细节,预处理的时候从第2个开始更新,匹配串要和$i$之前的自我匹配,$while里的j>0$容易忘

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=1000010;
     5 char a[N],b[N];
     6 int n,m,nxt[N];
     7 I void pre()
     8 {
     9     int j=0;nxt[1]=0;
    10     for(int i=1;i<m;i++)
    11     {
    12         while(j&&b[j+1]!=b[i+1])j=nxt[j];
    13         if(b[j+1]==b[i+1])j++;nxt[i+1]=j;
    14     }
    15 }
    16 
    17 I void kmp()
    18 {
    19     int j=0;
    20     for(int i=0;i<n;i++)
    21     {
    22         while(j&&b[j+1]!=a[i+1])j=nxt[j];
    23         if(b[j+1]==a[i+1])j++;
    24         if(j==m)printf("%d
    ",i-m+2),j=nxt[j];
    25     }
    26 }
    27 
    28 int main()
    29 {
    30     cin>>a+1>>b+1;
    31     n=strlen(a+1);m=strlen(b+1);
    32     pre();kmp();
    33     for(int i=1;i<=m;i++)printf("%d ",nxt[i]);
    34 }
    show you the code

     最小费用最大流(EK)

    EK,把bfs换成spfa就行了

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=5010;
     5 const int M=50010;
     6 const int inf=2147483647;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 struct node
    15 {
    16     int nxt,to,w,f;
    17 }g[M<<1];
    18 struct PRE
    19 {
    20     int id,u;
    21 }pre[N];
    22 int dist[N];
    23 bool vis[N];
    24 int head[N],cnt=1;
    25 int n,m,s,t;
    26 int cost;
    27 I void addedge(int u,int v,int w,int f)
    28 {
    29     g[++cnt].nxt=head[u];
    30     g[cnt].to=v;
    31     g[cnt].w=w;
    32     g[cnt].f=f;
    33     head[u]=cnt;
    34 }
    35 
    36 I bool spfa()
    37 {
    38     for(int i=1;i<=n;i++)dist[i]=inf;
    39     memset(vis,0,sizeof(vis));
    40     memset(pre,-1,sizeof(pre));
    41     queue<int>q;q.push(s);dist[s]=0;
    42     while(!q.empty())
    43     {
    44         int u=q.front();q.pop();vis[u]=0;
    45         for(int i=head[u];i;i=g[i].nxt)
    46         {
    47             int v=g[i].to,f=g[i].f,w=g[i].w;
    48             if(w&&dist[v]>dist[u]+f)
    49             {
    50                 dist[v]=dist[u]+f;
    51                 pre[v].u=u;pre[v].id=i;
    52                 if(!vis[v])q.push(v),vis[v]=1;
    53             }
    54         }
    55     }
    56     return dist[t]!=inf;
    57 }
    58 
    59 I int EK()
    60 {
    61     int maxflow=0;
    62     while(spfa())
    63     {
    64         int mi=inf;
    65         for(int i=t;i!=s;i=pre[i].u)mi=min(mi,g[pre[i].id].w);
    66         for(int i=t;i!=s;i=pre[i].u)g[pre[i].id].w-=mi,g[pre[i].id^1].w+=mi;
    67         maxflow+=mi;cost+=mi*dist[t];
    68     }
    69     return maxflow;
    70 }
    71 
    72 int main()
    73 {
    74     n=read();m=read();s=read();t=read();
    75     for(int i=1;i<=m;i++)
    76     {
    77         int x=read(),y=read(),w=read(),f=read();
    78         addedge(x,y,w,f);addedge(y,x,0,-f);
    79     }
    80     printf("%d ",EK());printf("%d",cost);
    81 }
    show you the code

    单源最短路径(dijkstra)

    关于spfa,

    它死了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=200010;
     4 struct node
     5 {
     6     int pos,dis;
     7     bool operator < (const node &x)const
     8     {
     9         return dis>x.dis;
    10     }
    11 };
    12 priority_queue<node>q;
    13 struct edge
    14 {
    15     int next,to,dis;
    16 }g[N];
    17 int head[N],cnt;
    18 int n,m,s;
    19 
    20 inline void addedge(int u,int v,int dis)
    21 {
    22     g[++cnt].next=head[u];
    23     g[cnt].to=v;
    24     g[cnt].dis=dis;
    25     head[u]=cnt;
    26 }
    27 
    28 bool vis[maxn];
    29 int dis[maxn];
    30 
    31 void dijkstra(int x)
    32 {
    33     for(int i=1;i<=n;i++)
    34     {
    35         dis[i]=2147483647;vis[i]=0;
    36     }
    37     q.push((node){x,0});
    38     dis[x]=0;
    39     while(!q.empty())
    40     {
    41         int u=q.top().pos;q.pop();
    42         if(vis[u])continue;
    43         vis[u]=1;
    44         for(int i=head[u];i;i=g[i].next)
    45         {
    46             int v=g[i].to;
    47             if(dis[v]>dis[u]+g[i].dis)
    48             {
    49                 dis[v]=dis[u]+g[i].dis;
    50                 if(!vis[v])
    51                 {
    52                     q.push((node){v,dis[v]});
    53                 }
    54             }
    55         }
    56     }
    57 }
    58 int main()
    59 {
    60     scanf("%d%d%d",&n,&m,&s);
    61     for(int i=1;i<=m;i++)
    62     {
    63         int x,y,z;
    64         scanf("%d%d%d",&x,&y,&z);
    65         addedge(x,y,z);
    66     }
    67     dijkstra(s);
    68     for(int i=1;i<=n;i++)
    69     {
    70         cout<<dis[i]<<" ";
    71     }
    72 }
    show you the code

     静态区间第k小(主席树)

    自我感觉主席树写的挺美观qwq,注意时间关系,离散化下标,前缀和和线段树二分思想

     1 #include<bits/stdc++.h>
     2 #define smid (l+r>>1)
     3 #define I inline
     4 using namespace std;
     5 const int N=2e5+10;
     6 I int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    11     return x*f;
    12 }
    13 int sum[N<<5],ls[N<<5],rs[N<<5],T[N],cnt;
    14 int n,m,d,a[N],b[N];
    15 
    16 I void bt(int &now,int l,int r)
    17 {
    18     now=++cnt;if(l==r)return;
    19     bt(ls[now],l,smid);bt(rs[now],smid+1,r);
    20 }
    21 
    22 I void modify(int &now,int pre,int l,int r,int pos)
    23 {
    24     now=++cnt;sum[now]=sum[pre]+1;ls[now]=ls[pre];rs[now]=rs[pre];
    25     if(l==r)return;
    26     if(pos<=smid)modify(ls[now],ls[pre],l,smid,pos);
    27     else modify(rs[now],rs[pre],smid+1,r,pos);
    28 }
    29 
    30 I int query(int now,int pre,int l,int r,int k)
    31 {
    32     if(l==r)return b[l];
    33     int s=sum[ls[now]]-sum[ls[pre]];
    34     if(s>=k)return query(ls[now],ls[pre],l,smid,k);
    35     else return query(rs[now],rs[pre],smid+1,r,k-s);
    36 }
    37 
    38 int main()
    39 {
    40     n=read();m=read();
    41     for(int i=1;i<=n;i++)a[i]=read(),b[i]=a[i];
    42     sort(b+1,b+1+n);d=unique(b+1,b+1+n)-b-1;
    43     bt(T[0],1,d);
    44     for(int i=1;i<=n;i++)
    45     {
    46         int x=lower_bound(b+1,b+1+d,a[i])-b;
    47         modify(T[i],T[i-1],1,d,x);
    48     }
    49     while(m--)
    50     {
    51         int l=read(),r=read(),k=read();
    52         printf("%d
    ",query(T[r],T[l-1],1,d,k));
    53     }
    54 }
    show you the code

     左偏树

    不太可能会考,不用$dsu$的版本很好写,如果加了$dsu$,注意一下$pop时f[ls[x]]=f[rs[x]]=f[x]=merge(ls[x],rs[x])$,因为并查集可能有多个儿子,并不是二叉树,所以要把其他儿子的根通过x也变成新的merge(ls[x],rs[x])(画个菊花图模拟一下就好啦)

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=100010;
     5 I int read()
     6 {
     7     int x=0,f=1;char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     9     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    10     return x*f;
    11 }
    12 int n,m;
    13 int f[N],val[N],ls[N],rs[N],dist[N];
    14 
    15 I int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    16 
    17 I int merge(int x,int y)
    18 {
    19     if(!x||!y)return x+y;
    20     if(val[x]>val[y]||(val[x]==val[y]&&x>y))swap(x,y);
    21     rs[x]=merge(rs[x],y);
    22     f[rs[x]]=x;
    23     if(dist[ls[x]]<dist[rs[x]])swap(ls[x],rs[x]);
    24     dist[x]=dist[rs[x]]+1;
    25     return x;
    26 }
    27 
    28 I void pop(int x)
    29 {
    30     val[x]=-1;f[ls[x]]=f[rs[x]]=f[x]=merge(ls[x],rs[x]);
    31 }
    32 
    33 int main()
    34 {
    35     n=read();m=read();for(int i=1;i<=n;i++)val[i]=read();
    36     dist[0]=-1;for(int i=1;i<=n;i++)f[i]=i;
    37     while(m--)
    38     {
    39         int cid=read();
    40         if(cid==1)
    41         {
    42             int x=read(),y=read();
    43             int r1=getf(x),r2=getf(y);
    44             if(val[x]==-1||val[y]==-1)continue;
    45             if(r1==r2)continue;
    46             f[r1]=f[r2]=merge(r1,r2);
    47         }
    48         if(cid==2)
    49         {
    50             int x=read();
    51             if(val[x]==-1){puts("-1");continue;}
    52             int r=getf(x);printf("%d
    ",val[r]);
    53             pop(r);
    54         }
    55     }
    56 }
    show you the code

    LCT

    注意画图模拟,,,顺序:$access->splay->rotate->nroot->pushup->pushdown->reverse->makeroot->link->split->cut$

    注意修改点权时,要把点移动到splay的根,这样没有影响

     1 #include<bits/stdc++.h>
     2 #define ls(x) ch[x][0]
     3 #define rs(x) ch[x][1]
     4 #define I inline
     5 using namespace std;
     6 const int N=100010;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 int n,m;
    15 int val[N],sum[N],ch[N][2],f[N],sta[N];
    16 bool rev[N];
    17 
    18 I void pushup(int x){sum[x]=val[x]^sum[ls(x)]^sum[rs(x)];}
    19 
    20 I bool nroot(int x){return ls(f[x])==x||rs(f[x])==x;}
    21 
    22 I void reverse(int x){rev[x]^=1;swap(ls(x),rs(x));}
    23 
    24 I void pushdown(int x)
    25 {
    26     if(!rev[x])return;
    27     if(ls(x))reverse(ls(x));
    28     if(rs(x))reverse(rs(x));
    29     rev[x]=0;
    30 }
    31 
    32 I void rotate(int x)
    33 {
    34     int y=f[x],z=f[y],k=rs(y)==x,w=ch[x][!k];
    35     if(nroot(y))ch[z][rs(z)==y]=x;ch[x][!k]=y;ch[y][k]=w;
    36     if(w)f[w]=y;f[x]=z;f[y]=x;pushup(y);
    37 }
    38 
    39 I void splay(int x)
    40 {
    41     int y=x,z=1;sta[z]=y;
    42     while(nroot(y))sta[++z]=y=f[y];
    43     while(z)pushdown(sta[z--]);
    44     while(nroot(x))
    45     {
    46         y=f[x];z=f[y];
    47         if(nroot(y))rotate((ls(y)==x)^(ls(z)==y)?x:y);
    48         rotate(x);
    49     }pushup(x);
    50 }
    51 
    52 I void access(int x)
    53 {
    54     for(int y=0;x;y=x,x=f[x])
    55     splay(x),rs(x)=y,pushup(x);
    56 }
    57 
    58 I int findroot(int x)
    59 {
    60     access(x);splay(x);
    61     while(ls(x))pushdown(x),x=ls(x);
    62     splay(x);
    63     return x;
    64 }
    65 
    66 I void makeroot(int x){access(x);splay(x);reverse(x);}
    67 
    68 I void link(int x,int y){makeroot(x);if(findroot(y)!=x)f[x]=y;}
    69 
    70 I void split(int x,int y){makeroot(x);access(y);splay(y);}
    71 
    72 I void cut(int x,int y)
    73 {
    74     makeroot(x);
    75     if(findroot(y)==x&&f[y]==x&&!ls(y))f[y]=rs(x)=0,pushup(x);
    76 }
    77 
    78 int main()
    79 {
    80     n=read();m=read();for(int i=1;i<=n;i++)val[i]=read();
    81     while(m--)
    82     {
    83         int op=read(),x=read(),y=read();
    84         if(op==0)split(x,y),printf("%d
    ",sum[y]);
    85         if(op==1)link(x,y);
    86         if(op==2)cut(x,y);
    87         if(op==3)splay(x),val[x]=y;
    88     }
    89 }
    show you the code

     欧拉路径(欧拉图的遍历)

    从$degree$为奇数的点开始(由欧拉路径性质),每次遍历出边中序号字典序最小的点(题目要求),并把这条双向边删掉,用$stack$存一下即可

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <stack>
     5 using namespace std;
     6 const int maxn = 1031;
     7 int G[maxn][maxn],du[maxn];
     8 int n,m;
     9 stack<int>S;
    10 void dfs(int u)
    11 {
    12     for(int v=1;v<=n;v++)
    13         if(G[u][v])
    14         {
    15             G[u][v]--;
    16             G[v][u]--;
    17             dfs(v);
    18         }
    19     S.push(u);
    20 }
    21 int main(){
    22 
    23     cin>>m;
    24     int u,v;
    25     for(int i=1;i<=m;i++){
    26         cin>>u>>v;
    27         n=max(n,u);
    28         n=max(n,v); 
    29         G[u][v]++;
    30         G[v][u]++;
    31         du[u]++;
    32         du[v]++;
    33     }
    34     int s=1;
    35     for(int i=1;i<=n;i++)
    36         if(du[i]%2==1) 
    37         {   
    38             s=i;
    39             break;
    40         }
    41     dfs(s);
    42     while(!S.empty())
    43     {
    44         cout<<S.top()<<endl;
    45         S.pop();
    46     }
    47     return 0;
    48 }
    show you the code

    三维偏序(CDQ分治)

    考虑两个排好序的序列合并,前面的对后面的做贡献

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 #define lowbit(x) (x&-x)
     4 using namespace std;
     5 const int N=100010;
     6 I int read()
     7 {
     8     int x=0,f=1;char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    10     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    11     return x*f;
    12 }
    13 
    14 struct node
    15 {
    16     int a,b,c,f,w;
    17 }q[N],t[N];
    18 int ans[N];
    19 int n,m;
    20 int bit[N<<1];
    21 
    22 I void add(int pos,int val)
    23 {
    24     while(pos<=m)bit[pos]+=val,pos+=lowbit(pos);
    25 }
    26 I int query(int pos)
    27 {
    28     int res=0;
    29     while(pos)res+=bit[pos],pos-=lowbit(pos);
    30     return res;
    31 }
    32 
    33 I bool cmp(node a,node b)
    34 {
    35     return a.a==b.a?(a.b==b.b?a.c<b.c:a.b<b.b):a.a<b.a;
    36 }
    37 
    38 I void cdq(int l,int r)
    39 {
    40     if(l==r)return;
    41     int mid=(l+r>>1);
    42     cdq(l,mid);cdq(mid+1,r);
    43     int i=l,j=mid+1,k=l;
    44     while(i<=mid&&j<=r)
    45     {
    46         if(q[i].b<=q[j].b)add(q[i].c,q[i].w),t[k++]=q[i++];
    47         else q[j].f+=query(q[j].c),t[k++]=q[j++];
    48     }
    49     while(i<=mid)add(q[i].c,q[i].w),t[k++]=q[i++];
    50     while(j<=r)q[j].f+=query(q[j].c),t[k++]=q[j++];
    51     for(i=l;i<=mid;i++)add(q[i].c,-q[i].w);
    52     for(i=l;i<=r;i++)q[i]=t[i];
    53 }
    54 
    55 int main()
    56 {
    57     n=read();m=read();
    58     for(int i=1;i<=n;i++)
    59     {
    60         q[i].a=read();q[i].b=read();q[i].c=read();q[i].w=1;
    61     }
    62     sort(q+1,q+1+n,cmp);
    63     int cnt=1;
    64     for(int i=2;i<=n;i++)
    65     {
    66         if(q[cnt].a==q[i].a&&q[cnt].b==q[i].b&&q[cnt].c==q[i].c)q[cnt].w++;
    67         else q[++cnt]=q[i];
    68     }
    69     cdq(1,cnt);
    70     for(int i=1;i<=cnt;i++)ans[q[i].f+q[i].w-1]+=q[i].w;
    71     for(int i=0;i<n;i++)printf("%d
    ",ans[i]);
    72 }
    show you the code

    单调栈求最大子矩阵

    维护$pre[i][j]表示(i,j)$向上最远的没被占领的地方,用一个递增单调栈维护每列的高h和往左最远的不小于它高度的列,加入$h$时,若$h$比栈顶小,则计算,并更新往左的最远列,否则入栈。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 const int N=2010;
     7 struct node
     8 {
     9     int h,x;
    10 }s[N];
    11 int a[N][N];
    12 int n,m;
    13 int ans;
    14 int pre[N][N];
    15 
    16 int main()
    17 {
    18     scanf("%d%d",&n,&m);
    19     for(int i=1;i<=n;i++)
    20     for(int j=1;j<=m;j++)
    21     {
    22         char x;
    23         cin>>x;
    24         if(x=='F')
    25         {
    26             pre[i][j]=pre[i-1][j]+1;
    27         }
    28     }
    29     for(int i=1;i<=n;i++)
    30     {
    31         int top=0;
    32         for(int j=1;j<=m+1;j++)
    33         {
    34             int xx=j;
    35             while(pre[i][j]<=s[top].h&&top)
    36             {
    37                 if(s[top].h)ans=max(ans,s[top].h*(j-s[top].x));
    38                 xx=s[top].x;
    39                 top--;
    40             }
    41             top++;
    42             s[top].h=pre[i][j];s[top].x=xx;
    43         }
    44     }cout<<ans*3;
    45 }
    show you the code

     高精度

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=20010;
     4 char tmp[N];
     5 struct bigint 
     6 {
     7     int num[N];
     8     int l;
     9 }x,y,z;
    10 
    11 bigint operator + (bigint a,bigint b)
    12 {
    13     bigint c;c.l=1;
    14     int x=0;
    15     while(c.l<=a.l||c.l<=b.l)
    16     {
    17         c.num[c.l]=a.num[c.l]+b.num[c.l]+x;//Õý³£¼Ó 
    18         x=c.num[c.l]/10;c.num[c.l]%=10;//½øλ 
    19         c.l++;
    20     }
    21     c.num[c.l]=x;//×îºóһλ½øµô£¨²»¹ÜÓÐûÓнø£© 
    22     if(c.num[c.l]==0)c.l--;//È¥0 
    23     return c;
    24 }
    25 
    26 bigint operator - (bigint a,bigint b)
    27 {
    28     if(a.l<b.l)swap(a,b),cout<<"-";//¸ºÊý 
    29     for(int i=1;i<=a.l;i++)
    30     {
    31         a.num[i]=a.num[i]-b.num[i];//Õý³£¼õ 
    32         if(a.num[i]<0)a.num[i]+=10,a.num[i+1]--;//½èλ 
    33     }
    34     while(a.num[a.l]==0&&a.l>1)a.l--;//È¥0 
    35     return a;
    36 }
    37 
    38 bigint operator * (bigint a,bigint b)
    39 {
    40     bigint c;c.l=a.l+b.l;
    41     for(int i=1;i<=a.l;i++)
    42     for(int j=1;j<=b.l;j++)
    43     c.num[i+j-1]+=a.num[i]*b.num[j];
    44     for(int i=1;i<c.l;i++)if(c.num[i]>9)c.num[i+1]+=c.num[i]/10,c.num[i]%=10;
    45     while(!c.num[c.l]&&c.l>1)c.l--;
    46     return c;
    47 }
    48 
    49 inline void print(bigint x)
    50 {
    51     for(int i=x.l;i>=1;i--)
    52     cout<<x.num[i];
    53 }
    54 
    55 int main()
    56 {
    57     //Õý¶Á×Ö·û£¬·´×ªÊý×飬´ÓµÍλ¿ªÊ¼´¦Àí 
    58     cin>>tmp;x.l=strlen(tmp);for(int i=0;i<x.l;i++)x.num[x.l-i]=tmp[i]-'0';
    59     cin>>tmp;y.l=strlen(tmp);for(int i=0;i<y.l;i++)y.num[y.l-i]=tmp[i]-'0';
    60     //z=x+y;print(z);
    61     //z=x-y;print(z);
    62     z=x*y;print(z);
    63 }
    show you the code

     最长上升(不上升)子序列(nlogn)

    d数组为满足的合法序列,用贪心的思路对于使len相等的多个元素,以最小(大)的结尾一定是最优的

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=100010;
     4 int a[N],d1[N],d2[N],n;
     5 int len1,len2;
     6 
     7 int main()
     8 {
     9     while(cin>>a[++n]);n--;
    10     d1[1]=a[1];d2[1]=a[1];
    11     len1=len2=1;
    12     for(int i=2;i<=n;i++)
    13     {
    14         if(d1[len1]>=a[i])d1[++len1]=a[i];
    15         else
    16         {
    17             int tmp=upper_bound(d1+1,d1+1+len1,a[i],greater<int>())-d1;
    18             d1[tmp]=a[i];
    19         }
    20         if(d2[len2]<a[i])d2[++len2]=a[i];
    21         else
    22         {
    23             int tmp=lower_bound(d2+1,d2+1+len2,a[i])-d2;
    24             d2[tmp]=a[i];
    25         }
    26     }
    27     cout<<len1<<endl<<len2;
    28 }
    show you the code

    最长公共子序列(nlogn)

    考虑LIS为一个数列和{1,2,3...n}的LCS,那么我们也可以把LCS转化为LIS,具体做法:用$b$中的$a[i],a[j]$的相对位置来重新定义$a[i]和a[j]$的大小关系。这样我们维护m[b[i]]=i的一个映射,如果$m[a[i]]<m[a[j]]$那么我们认为$“a[i]<a[j]”$。

     1 #include<bits/stdc++.h>
     2 #define I inline
     3 using namespace std;
     4 const int N=100010;
     5 typedef long long ll;
     6 const int inf=2147483647;
     7 I int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 
    15 int n,a[N],b[N],m[N],f[N],ans;
    16 
    17 int main()
    18 {
    19     n=read();
    20     for(int i=1;i<=n;i++)a[i]=read(),f[i]=inf;
    21     for(int i=1;i<=n;i++)b[i]=read(),m[b[i]]=i;
    22     f[1]=a[1];ans=1;
    23     for(int i=2;i<=n;i++)
    24     {
    25         if(m[a[i]]>f[ans]){f[++ans]=m[a[i]];continue;}
    26         int tmp=lower_bound(f+1,f+1+ans,m[a[i]])-f;
    27         f[tmp]=m[a[i]];
    28     }
    29     cout<<ans;
    30 }
    show you the code

     字典树求异或最大值

     1 void insert(int x)
     2 {
     3     int u=1;
     4     for(int i=(1<<30);i;i>>=1)
     5     {
     6         bool c=(i&x)?1:0;
     7         if(!ch[u][c])ch[u][c]=++cnt;
     8         u=ch[u][c];
     9     }
    10 }
    11 
    12 int query(int x)
    13 {
    14     int u=1,res=0;
    15     for(int i=(1<<30);i;i>>=1)
    16     {
    17         bool c=(i&x)?0:1;
    18         if(ch[u][c])res+=i,u=ch[u][c];
    19         else u=ch[u][!c];
    20     }return res;
    21 }
    show you the code
  • 相关阅读:
    Vim的分屏功能 | 酷壳 CoolShell.cn
    分享:Hadoop的Python框架指南
    KMP算法之另类图示分析
    C#cookie自动获取工具发布
    tmux Tutorial Split Terminal Windows Easily
    爱上MVC3~将系统的路由设置抽象成对象吧
    DDD~microsoft NLayerApp项目中的层次结构图
    不说技术~难得糊涂
    DDD~基础设施层
    基础才是重中之重~开发人员应用学会用throw
  • 原文地址:https://www.cnblogs.com/THRANDUil/p/11782661.html
Copyright © 2020-2023  润新知