• 模板


    有错的话欢迎大佬指出 会尽快订正的

    自己用的标准开头

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    int main()
    {
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
        return 0;
    } 
    开头

    头文件模板(防类似POJ的)

    #include <assert.h> //设定插入点
    #include <ctype.h> //字符处理
    #include <errno.h> //定义错误码
    #include <float.h> //浮点数处理
    #include <fstream.h> //文件输入/输出
    #include <iomanip.h> //参数化输入/输出
    #include <iostream.h> //数据流输入/输出
    #include <limits.h> //定义各种数据类型最值常量
    #include <locale.h> //定义本地化函数
    #include <math.h> //定义数学函数
    #include <stdio.h> //定义输入/输出函数
    #include <stdlib.h> //定义杂项函数及内存分配函数#include <string.h> //字符串处理
    #include <strstrea.h> //基于数组的输入/输出
    #include <time.h> //定义关于时间的函数#include <wchar.h> //宽字符处理及输入/输出
    #include <wctype.h> //宽字符分类//////////////////////////////////////////////////////////////////////////标准 C++ (同上的不再注释)
    #include <algorithm> //STL 通用算法
    #include <bitset> //STL 位集容器
    #include <cctype>#include <cerrno>
    #include <clocale>
    #include <cmath>
    #include <complex> //复数类#include <cstdio>#include <cstdlib>
    #include <cstring>#include <ctime>
    #include <deque> //STL 双端队列容器
    #include <exception> //异常处理类
    #include <fstream>
    #include <functional> //STL 定义运算函数(代替运算符)
    #include <limits>#include <list> //STL 线性列表容器#include <map> //STL 映射容器
    #include <iomanip>#include <ios> //基本输入/输出支持#include <iosfwd> //输入/输出系统使用的前置声明
    #include <iostream>
    #include <istream> //基本输入流
    #include <ostream> //基本输出流
    #include <queue> //STL 队列容器
    #include <set> //STL 集合容器#include <sstream> //基于字符串的流
    #include <stack> //STL 堆栈容器
    #include <stdexcept> //标准异常类
    #include <streambuf> //底层输入/输出支持
    #include <string> //字符串类
    #include <utility> //STL 通用模板类
    #include <vector> //STL 动态数组容器
    #include <cwchar>
    #include <cwctype>using namespace std;//////////////////////////////////////////////////////////////////////////C99 增加
    #include <complex.h> //复数处理
    #include <fenv.h> //浮点环境
    #include <inttypes.h> //整数格式转换
    #include <stdbool.h> //布尔环境
    #include <stdint.h> //整型环境
    #include <tgmath.h> //通用类型数学宏
    头文件

    对拍

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long 
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    ll t,ac,st,t1,t2;
    int main()
    {
        
        while(1)
        {
            t++;
            system("rd.exe");//system("C:\Users\Stuedent\Desktop\对拍\td.exe");//生成//system("rd.exe");绝对路径 
            st=clock();
            system("bl.exe");//system("C:\Users\Stuedent\Desktop\对拍l.exe");//暴力
            t1=clock()-st;
            st=clock(); 
            system("dq.exe");//system("C:\Users\Stuedent\Desktop\对拍\dq.exe");//当前 
            t2=clock()-st;
            if(system("fc testdata2.out testdata.out"))//if(system("fc C:\Users\Stuedent\Desktop\对拍\testdata2.out C:\Users\Stuedent\Desktop\对拍\testdata.out"))
            {
                puts("WA");
                //return 0;
            }
            else
            {
                ac++;
                printf("Accept,  测试点 #%lld,  bl用时 %lldms,  dq用时 %lldms  ",t,t1,t2);
                printf("  正确%lld, 总共%lld
    ",ac,t);
            }
        }
        return 0;
    }
    对拍

    重载运算符

    重载运算符

    快速幂&快速乘

    const p=;
    inline ll ksc(ll a,llb)//快速乘
    {
        ll ans=0;
        while(b)
        {
            if(b&1) ans=(ans+a)%p;
            a=(a+a)%p;
            b>>=1;
        }
    } 
    //防爆版 
    inline ll ksc(ll a,ll b)
    {
        ll ans=a*b-(ll)((long double)a*b/p+0.5)*p;
        return ans<0?ans+p:ans;
    }
    inline ll ksm(ll a,ll b)//快速幂 
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;//ksc(ans,a);
            a=(a*a)%p;//ksc(a,a;
            b>>=1;
        }
        return ans;
    }
    快速幂&快速乘

    矩阵乘法&矩阵快速幂

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const ll p=; 
    const int N=;
    struct xin{
        ll a[N+10][N+10];
    };
    inline xin jzmul(xin a,xin b)//a[i][o],b[o][j]   矩阵乘法  
    {
        xin ans;
        for(int i=1;i<=N;i++)
        for(int j=1;j<=N;j++)
        {
            ans.a[i][j]=0;
            for(int o=1;o<=N;o++)
              ans.a[i][j]=(ans.a[i][j]+a.a[i][o]*b.a[o][j])%p;
        } 
        return ans;
    }
    inline xin jzksm(xin a,ll b)// 矩阵快速幂 
    {
        xin ans;
        while(b)
        {
            if(b&1) ans=jzmul(ans,a);
            a=jzmul(a,a);
            b>>=1; 
        }
        return ans;
    }
    int main()
    {
        
        return 0;
    }
    矩阵乘法&矩阵快速幂(一般版)

     gcd

    inline ll gcd(ll a,ll b)
    {
        return b?gcd(b,a%b):a; 
    }
    gcd

    exgcd

    //exgcd(n,p,x,y) 解n在模p时逆元 答案为x  return值为np的gcd 
    // ax+by=z ---> z(ax+by)=1; 
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
      if(!b){x=1;y=0;return a;}
      ll d=exgcd(b,a%b,x,y);
      ll tmp=x;x=y;y=tmp-a/b*y;
      return d;
    }
    /*
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r; 
    }
    ll a,b,p,x,y;
    inline ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b){x=1,y=0;return a;}
        ll d=exgcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
    inline ll ny()
    {
        return exgcd(a,p,x,y)==1?(x%p+p)%p:1;
    }
    int main()
    {
        a=read();p=read();
        ll inv=ny(); 
        printf("%lld
    ",inv);
    } 
    */ 
    exgcd

    高斯消元

    const int N=;
    const double cc=1e-8; 
    int n;
    double c[N][N],b[N];//c[][] 变量 b[]常数 
    void gaosi()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            if(fabs(c[j][i])>cc)//最好取值最大的防爆 
            {
                for(int k=1;k<=n;k++) swap(c[i][k],c[j][k]);
                swap(b[i],b[j]); 
            }
            for(int j=1;j<=n;j++)
            {
                if(i==j) continue;
                double tmp=c[j][i]/c[i][i];
                for(int k=i;k<=n;k++) c[j][k]-=c[i][k]*tmp;
                b[j]-=b[i]*tmp;
            }
        }
    }
        
    高斯消元

    中国剩余定理

    const int N=;
    ll n; 
    ll sum,ans;
    ll s[N],p[N];//s[]余数 p[]模数 
    inline ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b){x=1,y=0;return a;}
        ll d=exgcd(b,a%b,x,y);
        ll tmp=x;x=y;y=tmp-a/b*y;
        return d;
    }
    void crt()
    {
        sum=1; 
        for(int i=1;i<=n;i++) sum*=p[i];
        for(int i=1;i<=n;i++)
        {
            ll x,y;
            exgcd(sum/p[i],p[i],x,y);
            ans=(ans+x*(sum/p[i])*s[i]%sum+sum)%sum;
        } 
    }
    中国剩余定理

    扩展中国剩余定理

    const int N=;
    ll n;
    ll ans=0; 
    ll s[N],p[N];
    inline ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(!b){x=1,y=0;return a;}
        ll d=exgcd(b,a%b,x,y);
        ll tmp=x;x=y;y=tmp-a/b*y;
        return d;
    }
    inline ll ksc(ll a,ll b,ll p)
    {
        ll ans=a*b-(ll)((long double)a*b/p+0.5)*p;
        return ans<0?ans+p:ans;
    }
    void excrt()
    {
        ll pq,sq,w;
        for(int i=1;i<=n;i++)
        {
            if(p[i]==1) continue;
            pq=p[i];sq=s[i];
            w=i;
            break;
        }
        for(int i=1;i<=n;i++)
        {
            if(p[i]==1) continue;
            ll x,y,c=((s[i]-sq)%p[i]+p[i])%p[i]; //差值 
            ll gcd=exgcd(pq,p[i],x,y),duo=p[i]/gcd; //防爆ll处理   pqx+p[i]y=s[i]-sq 两边除gcd 
            x=ksc(x,c/gcd,duo); 
            sq+=x*pq;
            pq*=duo; 
            sq=(sq%pq+pq)%pq;
        }
        //答案(sq%pq+pq)%pq;
    }
    扩展中国剩余定理

    线性筛

    const int N=;
    int n,m; 
    int prime[N],top,vis[N];
    void xxs(int mx)//线性筛  
    {
        vis[0]=vis[1]=1; //1为不是0为是 
        for(int i=2;i<=mx;i++)
        {
            if(!vis[i]) prime[++top]=i;
            for(int j=1;j<=top&&prime[j]*i<=mx;j++)
            {
                vis[prime[j]*i]=1;
                if(!(i%prime[j])) break;
            }
        }
    }
    线性筛

    线性求欧拉函数

    const int N=;
    ll vis[N],prime[N],top,oula[N];
    void xxoula(int mx)
    {
        vis[0]=vis[1]=1;//1为不是0为是 
        oula[0]=0;oula[1]=1;
        for(int i=2;i<=mx;i++)
        {
            if(!vis[i]){prime[++top]=i;oula[i]=i-1;}
            for(int j=1;j<=top&&prime[j]*i<=mx;j++)
            {
                vis[prime[j]*i]=1;
                if(!(i%prime[j])){oula[prime[j]*i]=oula[i]*prime[j];break;}
                oula[prime[j]*i]=oula[i]*(prime[j]-1);
            }
        }
    } 
    线性求欧拉函数

    线性筛约数个数

    const int N=;
    ll vis[N],prime[N],top,ge[N],mnge[N];//mnge i的最小素因子个数 
    void xxyg(int mx)//ge[n]=(1+a1)(1+a2)...(1+an)
    {
        vis[0]=vis[1]=1;
        ge[0]=0;mnge[1]=1;ge[1]=1;
        for(int i=2;i<=mx;i++)
        {
            if(!vis[i]){prime[++top]=i,ge[i]=2;mnge[i]=1}
            for(int j=1;j<=top&&prime[j]*i<=mx;j++)
            {
                vis[prime[j]*i]=1; 
                if(!(i%prime[j])){mnge[prime[j]*i]=mnge[i]+1;ge[prime[j]*i]=ge[i]/(mnge[i]+1)*(mnge[prime[j]*i]+1);break;}
            }
            ge[prime[j]*i]=ge[i]*2;//=ge[i]*ge[prime[j]];
            mnge[prime[j]*i]=1;
        }
    }
    线性筛约数个数

    线性筛约数和

    const int N=;
    ll vis[N],prime[N],top,he[N],dbhe[N];//dbhe 最小素因子等比数列和 
    void xxyh(int mx)//he[i]=(1+p1+p1^2+...+p1^a1)(1+p2+p2^2+..+p2^a2)...(1+pn+pn^2+..+pn^an) 
    {
        vis[0]=vis[1]=1;
        he[0]=0;dbh[1]=1;he[1]=1;
        for(int i=2;i<=mx;i++)
        {
            if(!vis[i]){prime[++top]=i;he=1+i;dbhe[i]=1+i;}
            for(int j=1;j<=top&&prime[j]*i<=mx;j++)
            {
                vis[priem[j]*i]=1;
                if(!(i%prime[j])){dbhe[prime[j]*i]=dbhe[i]*prime[j]+1;he[prime[j]*i]=he[i]/dbhe[i]*dbhe[prime[j]*i];break;}
                he[prime[j]*i]=he[i]*(1+prime[j])//=he[i]*he[prime[j]
                dbhe[prime[j]*i]=1+prime[j];
            }
        }
    }
    线性筛约数和

    线性筛莫比乌斯函数

    const int N=;
    int prime[N],vis[N],top,mu[N];
    void xxmu(int mx)
    {
        vis[0]=vis[1]=1;
        mu[1]=1;
        for(int i=2;i<=mx;i++)
        {
            if(!vis[i]){prime[++top]=i;mu[i]=-1;}
            for(int j=1;j<=top&&prime[j]*i<=mx;j++)
            {
                vis[prime[j]*i]=1;
                if(i%prime[j]==0){mu[prime[j]*i]=0;break;}
                mu[prime[j]*i]=-mu[i];
            }
        }
    } 
    线性筛莫比乌斯函数

    Styuls自用样式

    //part1//part1//part1//part1//part1//part1//part1//part1//part1//part1
    .am-form-field
    {
        border-radius: 100px 100px 100px 100px!important;
    }
    #app-body-new
    {
        top:0px!important;
    }
    //part2//part2//part2//part2//part2//part2//part2//part2//part2//part2
    /* i really want this to be global */
    
    /*图片地址https://imgse.com/i/5dbGZe*/
    body
    {
        background: url("")/*地址*/ no-repeat;
        background-attachment: fixed;
        background-size: 100%;
    }
    
    #app-sidenav
    {
        background: none;
    }
    
    a[data-v-3e5191a6]:hover,.popup-button:hover
    {
        border-radius: 10px 10px 10px 10px;
        opacity:0.8;
        color: #000;
        transition: color 1s,background 0.45s,box-shadow 0.45s;
    }
    
    a[data-v-3e5191a6],.popup-button
    {
        background:none;
        color: #fff0;
    
        filter: none !important;
    }
    
    i[data-v-7e88b118]
    {
        color: #fff0;
        width: 4em;
        height: 3.8em;
        padding: 1.2em 0em 0em 0em;
    }
    
    div[data-v-7e88b118]
    {
        background-color: #fff0 !important;
    }
    
    
    i[data-v-7e88b118]:hover
    {
        color: #000;
    }
    
    a[data-v-7e88b118]
    {
        filter: invert(70%);
    }
    
    .popup-button
    {
        height: 4em;
    /*     opacity:0; */
    }
    
    .content
    {
        height: 5em !important;
        background: rgba(0,0,0,0);
    }
    
    .bread-crumb[data-v-3c5eed85]
    {
        padding-top: 0;
    }
    
    .width-wrap>h1
    {
        margin: 0;
    }
    
    .lg-content
    {
        margin: 0px 0px 0px 0px;
        padding: 0px 0px 0px 65px;
    }
    
    .lg-article
    {
        background: #fff;
        border-radius: 15px 15px 15px 15px;
        box-shadow: 1px 1px 2px #000;
        opacity:0.8;
    }
    
    .lg-summary
    {
        background: #fff;
        border-radius: 15px 15px 15px 15px;
        box-shadow: 1px 1px 2px #000;
        opacity:0.8;
    }
    
    .am-viewport
    {
        border-radius: 5px 5px 5px 5px;
        opacity:0.8;
    }
    
    .am-btn,.am-btn:visited,am.btn:active
    {
        border-radius: 100px 100px;
        border-color:#000;
        opacity:0.8;
        background-color:#000;
    }
    
    .am-btn:hover
    {
        border-color:#FFF;
        background-color:#FFF;
        color: #000;
        transition: color 1s,background 1s;
    }
    
    .lg-toolbar
    {
        background: #fff0;
        border: none;
    }
    
    .am-collapse
    {
        box-shadow: 2px 2px 2px #000;
        background-color: white;
    }
    
    .lg-header, .lg-header-list>li
    {
        background-color: white;
        color: #000 !important;
    }
    
    .lg-header-li
    {
        color: #000 !important;
    }
    .am-form-field
    {
        border-radius: 100px 100px 100px 100px;
        opacity:0.8;
        border-color:#000!important;
    }
    
    .am-input-group-label
    {
        border-radius: 0px 100px 100px 0px!important;
        color:#FFF!important;
        background:#000!important;
        border-color:#000!important;
    }
    
    .lg-table-bg0
    {
        background: #fff;
        border-radius: 12px 12px 12px 12px;
        opacity:0.8;
        box-shadow: 1px 1px 2px #000;
    }
    
    .lg-table-bg1
    {
        background: #fff;
        border-radius: 12px 12px 12px 12px;
        box-shadow: 1px 1px 2px #000;
    }
    
    .lg-table-bg0 .am-progress
    {
        box-shadow: none;
        border-radius: 0;
        opacity:0.8;
    }
    
    .am-pagination>li
    {
        background: #fff;
        border-radius: 20px 20px 20px 20px;
        opacity:0.8;
        box-shadow: 1px 1px 2px #000;
        margin: 4px 0px 0px 4px;
    }
    
    .am-comment-main
    {
        border: 0px solid;
        background: #fff;
        border-radius: 20px 20px 20px 20px;
        opacity:0.8;
        box-shadow: 2px 2px 2px #000;
    }
    .am-comment-main::after,.am-comment-main::before
    {
        display: none;
    }
    .am-comment-hd
    {
        background: #fff;
        border-radius: 12px 12px 12px 12px;
        opacity:0.8;
    }
    .am-comment-bd
    {
        background: #fff;
        border-radius: 12px 12px 12px 12px;
        opacity:0.8;
    }
    .am-panel-primary
    {
       background: #fff;
    }
    .am-pagination>li>a
    {
       background: #fff0;
        border:0px solid;
        margin: 2px 2px 2px 2px;
    }
    .am-pagination>li>a:hover
    {
       background: #fff0;
        border:0px solid;
        color: #000;
    }
    .am-pagination .am-active>a
    {
        background: #fff0;
        color: #000;
        font-weight: bold;
    }
    .am-pagination .am-active>a:hover
    {
        background: #fff0;
        color: #000;
    }
    .lg-sidebar-list>li
    {
        margin: 5px 5px 5px 5px;
       border-radius: 20px 20px 20px 20px;
        opacity:0.8;
       box-shadow: 1px 1px 2px #000;
    }
    .lg-sidebar-list
    {
        box-shadow: none;
    }
    code,pre
    {
        font-family: consolas;
    }
    .am-nav>li.am-active>a, .am-nav>li.am-active>a:focus, .am-nav>li.am-active>a:hover
    {
        background: none;
        font-weight: bold;
        color: #000;
    }
    .am-nav>li>a:focus, .am-nav>li>a:hover
    {
        background: none;
        color: #000;
    }
    #app-footer, #app-header
    {
        margin-left: 0em;
        background: rgba(51,51,51,0)!important;
    }
    a:hover,.width-wrap>h1
    {
        color: #000;
    }
    .popup[data-v-46951e14]
    {
        border: none;
    }
    .popup-wrap::before
    {
        content: "";
        position: absolute;
        top: 0px;
        left: 0px;
        width: 100%;
        height: 100%;
        background: #fff;
        border-radius: 15px 15px 15px 15px;
        opacity:0.8;
        box-shadow: 2px 2px 1px #000;
        z-index: -1;
    }
    .tip-twitter
    {
        background-color: #fff;
        border-radius: 100px 100px 100px 100px;
        opacity:0.8;
        color: #000;
        box-shadow: 0px 0px 20px #000;
    }
    .lg-record-tile
    {
        border-radius: 20px 20px 20px 20px;
        opacity:0.8;
        box-shadow: 2px 2px 2px #000;
    }
    .lg-record-tile>small:first-child
    {
        text-align: center;
        padding-left: 0px;
    }
    .am-progress
    {
        box-shadow: 2px 2px 2px #000;
        border-radius: 100px 100px 100px 100px;
        opacity:0.8;
    }
    .lg-left .center>img
    {
        border: none;
    }
    .icon-btn,.colored,.lg-article p a,.fas.fa-search
    {
        color: #000!important;
    }
    .search-wrap.show
    {
      background:#000;
    }
    .am-pagination.am-pagination-centered li a
    {
        color:#000;
    }
    .am-pagination.am-pagination-centered li a:visited,.am-pagination.am-pagination-centered li a:active,.am-pagination.am-pagination-centered li a:link
    {
        border-radius: 20px 20px 20px 20px!important;
    }
    .am-btn-primary:focus
    {
        color: #FFF;
        background:#000;
        border-color:#000;
        outline:none;
    }
    #app-body-new
    {
        top:-50px;
    }
    .center
    {
        background:#FFF!important;
        border-color:rgba(0,0,0,0)!important;
        box-shadow:none!important;
    }
    .center[data-v-98f4ade8]
    {
        color:#FFF!important;
        background:#000!important;
    }
    .sites span[data-v-27d0876a],.apps a[data-v-27d0876a],.popup[data-v-27d0876a]
    {
        color:#FFF!important;
        background:#000!important;
    }
    .popup[data-v-27d0876a]
    {
        margin-left:0em;
        position:absolute;
        top:-27px!important;
    }
    自用样式

    基本高精度

    struct node
    {
        int a[1100],l;
        node()
        {
            memset(a,0,sizeof(a));
            l = 1;
        }
        friend inline node operator *(int x,node &y)
        {
            node ret; ret.l = y.l+1;
            for (int i = 1;i <= y.l;++i)
            {
                ret.a[i] += y.a[i]*x;
                ret.a[i+1] += ret.a[i]/10;
                ret.a[i] %= 10;
            }
            if (ret.a[ret.l] == 0) ret.l--;
            return ret;
        }
        friend inline node operator -(node x,node y)
        {
            node z; z.l = max(x.l,y.l);
            for (int i = 1;i <= z.l;++i)
            {
                z.a[i] = x.a[i]-y.a[i];
                while (z.a[i] < 0)
                    z.a[i] += 10,x.a[i+1]--;
            }
            while (z.l > 1&&z.a[z.l] == 0)z.l--;
            return z;
        }
        friend inline node operator +(node &x,int y)
        {
            node ret = x;
            ret.a[1] += y;
            for (int i = 1;i <= ret.l;++i)
            {
                if (ret.a[i] >= 10)
                    ret.a[i]-=10,ret.a[i+1]++;
                else break;
            }
            if (ret.a[ret.l+1]) ret.l++;
            return ret;
        }
        inline void print()
        {
            for (int i = l;i >= 1;--i)
                printf("%d",this->a[i]);
        }
    }
    基本高精度模板(暂时别人风格)

    FFT

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    #define E complex<double>
    const int N=10000000;
    const double pi=acos(-1);
    int n,m,l,r[N];
    E a[N],b[N];
    void fft(E *a,int f){
        for(int i=0;i<n;i++)if(i<r[i])swap(a[i],a[r[i]]);
        for(int i=1;i<n;i<<=1){
            E wn(cos(pi/i),f*sin(pi/i)); 
            for(int p=i<<1,j=0;j<n;j+=p){
                E w(1,0);
                for(int k=0;k<i;k++,w*=wn){
                    E x=a[j+k],y=w*a[j+k+i];
                    a[j+k]=x+y;a[j+k+i]=x-y;  
                }
            }
        }
    }
    int main(){
        n=read();m=read();
        for(int i=0;i<=n;i++)a[i]=read();
        for(int i=0;i<=m;i++)b[i]=read();
        m+=n;for(n=1;n<=m;n<<=1)l++;
        for(int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
        fft(a,1);fft(b,1);
        for(int i=0;i<=n;i++)a[i]=a[i]*b[i];
        fft(a,-1);
        for(int i=0;i<=m;i++)printf("%d ",(int)(a[i].real()/n+0.5));
    }
    FFT

    NTT

    const ll p=,G=3,N=;//N记得至少开两倍 
    inline void ntt(ll *a,ll n,ll kd)
    {
        for(int i=0;i<n;i++)
        if(i<rev[i])
          swap(a[i],a[rev[i]]);
        for(int i=1;i<n;i<<=1)
        {
            ll gn=ksm(G,(p-1)/(i<<1));
            for(int j=0;j<n;j+=(j<<1))
            {
                ll t1,t2,g=1;
                for(int k=0;k<i;k++,g=g*gn%p)
                {
                    t1=a[j+k],t2=g*a[j+k+i]%p;
                    a[j+k]=(t1+t2)%p,a[j+k+i]=(t1-t2+p)%p; 
                }
            }
        }
        if(kd==1) return;
        ll ny=ksm(n,p-2);
        reverse(a+1,a+n);
        for(int i=0;i<n;i++) a[i]=a[i]*ny%p;
    }
    NTT

    倍增版Pollard-Rho

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    #define p1 printf("Prime
    ")
    #define p2 printf("%lld
    ",mx);
    #define enter puts("") 
    const ll M=(1<<7)-1;
    ll n,mx;
    int a[5]={2,3,5,7,11};
    inline void write(ll x)
    {
        if(x < 0) x = -x, putchar('-');
        if(x >= 10) write(x / 10);
        putchar(x % 10 + '0');
    }
    inline ll ksc(ll a,ll b,ll p)
    {
        ll ans=a*b-(ll)((long double)a*b/p+0.5)*p;
        return ans<0?ans+p:ans;
    }
    inline ll ksm(ll a,ll b,ll p)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ksc(ans,a,p);
            a=ksc(a,a,p);
            b>>=1;
        } 
        return ans;
    }
    inline ll gcd(ll a,ll b)
    {
        return (!b)?a:gcd(b,a%b);
    }
    inline ll f(ll x,ll a,ll p)
    {
        return (ksc(x,x,p)+a)%p;
    }
    inline bool pd(ll a,ll d,ll n)
    {
        ll tmp=ksm(a,d,n);
        if(tmp==1) return 1;
        while(d!=n-1&&tmp!=n-1&&tmp!=1) tmp=ksc(tmp,tmp,n),d<<=1;
        return tmp==n-1;
    }
    inline bool miller_rabin(ll n)
    {
        if(n==1) return 0;
        for(int i=0;i<5;i++)
        {
            if(n==a[i]) return 1;
            if(!(n%a[i])) return 0;
        }
        ll d=n-1;
        while(!(d&1)) d>>=1;
        for(int i=1;i<=5;i++)
        {
            ll a=rand()%(n-2)+2;
            if(!pd(a,d,n)) return 0;
        }
        return 1;
    }
    inline ll pollard_rho(ll n)
    {
        for(int i=0;i<5;i++)
        if(n%a[i]==0) return a[i];
        ll x=rand(),y=x,t=1,a=rand()%(n-2)+2;
        for(int k=2;;k<<=1,y=x)
        {
            ll q=1;
            for(int i=1;i<=k;i++)
            {
                x=f(x,a,n);
                q=ksc(q,abs(x-y),n);
                if(!(i&M))
                {
                    t=gcd(q,n);
                    if(t>1) break;
                }
            }
            if(t>1||(t=gcd(q,n))>1) break;
        }
        return t;
    }
    inline void find(ll x)
    {
        if(x==1||x<=mx) return;
        if(miller_rabin(x)){mx=max(mx,x);return;}
        ll p=x;
        while(p==x) p=pollard_rho(x);
        while(x%p==0) x/=p;
        find(p);find(x);
    }
    int main()
    {
        srand(time(0));
        ll t=read();
        while(t--)
        {
            n=read();
            mx=0;
            find(n);
            if(mx==n) p1;
            else write(mx), enter;    
        } 
        return 0;
    }
    倍增版Pollard-Rho

    多项式求逆

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<1)+(s<<3)+c;
        return s*r;
    } 
    const ll p=998244353,G=3,N=2100000;
    ll n; 
    ll rev[N];
    ll a[N],b[N],c[N];
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    inline void ntt(ll *a,ll n,ll kd)
    {
        for(ll i=0;i<n;i++)
        if(i<rev[i])
          swap(a[i],a[rev[i]]);
        for(ll i=1;i<n;i<<=1)
        {
            ll gn=ksm(G,(p-1)/(i<<1));
            for(ll j=0;j<n;j+=(i<<1))
            {
                ll t1,t2,g=1;
                for(ll k=0;k<i;k++,g=g*gn%p)
                {
                    t1=a[j+k],t2=g*a[j+k+i]%p;
                    a[j+k]=(t1+t2)%p,a[j+k+i]=(t1-t2+p)%p;
                }
            }
        }
        if(kd==1) return;
        ll ny=ksm(n,p-2); 
        reverse(a+1,a+n);
        for(ll i=0;i<n;i++) a[i]=a[i]*ny%p;
    }
    inline void work(ll deg,ll *a,ll *b)// B=2B'-CB^2
    {
        if(deg==1){b[0]=ksm(a[0],p-2);return;}
        work((deg+1)>>1,a,b);
        ll len=0,sum=1;
        for(;sum<(deg<<1);sum<<=1,len++);
        for(ll i=1;i<sum;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
        for(ll i=0;i<deg;i++) c[i]=a[i];
        for(ll i=deg;i<sum;i++) c[i]=0;
        ntt(c,sum,1);ntt(b,sum,1);
        for(ll i=0;i<sum;i++) b[i]=(2-c[i]*b[i]%p+p)%p*b[i]%p;
        ntt(b,sum,-1);
        for(ll i=deg;i<sum;i++) b[i]=0;
    }
    int main()
    {
        n=read();
        for(ll i=0;i<n;i++) a[i]=read();
        work(n,a,b);
        for(ll i=0;i<n;i++) printf("%lld ",b[i]); 
        return 0;
    }
    多项式求逆

    多项式除法

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<1)+(s<<3)+c;
        return s*r;
    } 
    const ll p=998244353,G=3,N=2100000;
    ll n; 
    ll rev[N];
    ll a[N],b[N],c[N];
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    inline void ntt(ll *a,ll n,ll kd)
    {
        for(ll i=0;i<n;i++)
        if(i<rev[i])
          swap(a[i],a[rev[i]]);
        for(ll i=1;i<n;i<<=1)
        {
            ll gn=ksm(G,(p-1)/(i<<1));
            for(ll j=0;j<n;j+=(i<<1))
            {
                ll t1,t2,g=1;
                for(ll k=0;k<i;k++,g=1ll*g*gn%p)
                {
                    t1=a[j+k],t2=1ll*g*a[j+k+i]%p;
                    a[j+k]=(t1+t2)%p,a[j+k+i]=(t1-t2+p)%p;
                }
            }
        }
        if(kd==1) return;
        ll ny=ksm(n,p-2); 
        reverse(a+1,a+n);
        for(ll i=0;i<n;i++) a[i]=1ll*a[i]*ny%p;
    }
    inline void work(ll deg,ll *a,ll *b)// B=2B'-CB^2
    {
        if(deg==1){b[0]=ksm(a[0],p-2);return;}
        work((deg+1)>>1,a,b);
        ll len=0,sum=1;
        for(;sum<(deg<<1);sum<<=1,len++);
        for(ll i=1;i<sum;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
        for(ll i=0;i<deg;i++) c[i]=a[i];
        for(ll i=deg;i<sum;i++) c[i]=0;
        ntt(c,sum,1);ntt(b,sum,1);
        for(ll i=0;i<sum;i++) b[i]=1ll*(2-1ll*c[i]*b[i]%p+p)%p*b[i]%p;
        ntt(b,sum,-1);
        for(ll i=deg;i<sum;i++) b[i]=0;
    }
    多项式除法

    多项式除法&取模

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const ll p=998244353,G=3,N=400010;
    ll n,m;
    ll f[N],g[N],q[N],r[N],inv[N],rev[N],c[N];
    ll tmp1[N],tmp2[N];
    inline ll ksm(ll a,ll b)//..快速幂 
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    inline void ntt(ll *a,ll n,ll kd)//ntt日常操作 
    {
        for(int i=0;i<n;i++)
        if(i<rev[i])
          swap(a[i],a[rev[i]]);
        for(int i=1;i<n;i<<=1)
        {
            ll gn=ksm(G,(p-1)/(i<<1));
            for(int j=0;j<n;j+=(i<<1))
            {
                ll t1,t2,g=1;
                for(int k=0;k<i;k++,g=g*gn%p)
                {
                    t1=a[j+k],t2=g*a[j+k+i]%p;
                    a[j+k]=(t1+t2)%p,a[j+k+i]=(t1-t2+p)%p; 
                }
            }
        }
        if(kd==1) return;
        ll ny=ksm(n,p-2);
        reverse(a+1,a+n);
        for(int i=0;i<n;i++) a[i]=a[i]*ny%p;
    }
    inline void cl(ll *a,ll *b,ll n,ll m,ll len,ll w)//处理 
    {
        for(int i=0;i<len;i++) tmp1[i]=i<n?a[i]:0;//复制 清空多余//因为tmp被使用多遍 而在做ntt时 用的是长度为len的
        for(int i=0;i<len;i++) tmp2[i]=i<m?b[i]:0;//而有效的值只有它的得出的长度 后面其它的在模意义下都被清掉了 但之前在写的时候有的地方并没有清
                                                  //为了避免出错所以一定要清空 (在这个代码里)//..不要打成 i<n?tmp1[i]=a[i]:0;...只有像我这种蒟蒻才会犯这种错误吧 
        for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(w-1));//蝴蝶 
    }
    inline void polyinv(ll *a,ll *b,ll ed)//递推版  
    {
        b[0]=ksm(a[0],p-2);//设初始值  a*b=1(mod=x)b的值 
        for(int k=1,j=0;k<=(ed<<1);k<<=1,j++)//从两个长度为k的多项式a,b递推  
        {//!!因为这份代码的递推算的是 两个长度为a的多项式在模(m^k)次下的逆元
         //所以如果直接用ed为条件只会推出小于ed的逆元 所以ed要再乘一倍 
         //所以多项式总共需要的范围要为4倍所以N要4倍 
            ll len=k<<1;             //len 两式子计算后大小 
            cl(a,b,k,k,len,j+1);//处理//j+1 要看len调整 因为len乘上了一倍 所以j在处理时也要加上1 之前没有加被坑了好久 
            ntt(tmp1,len,1);ntt(tmp2,len,1);//注意不要直接用a,b算 因为ntt后原多项式的值会变 为了方便所以先复制一遍在用复制的多项式算 
            for(int i=0;i<len;i++) b[i]=tmp2[i]*(2ll-tmp1[i]*tmp2[i]%p+p)%p;//求逆
            ntt(b,len,-1);
            for(int i=k;i<len;i++) b[i]=0;//清空会被模的 //!!!不能删 因为下次递推是直接把0--len都作为有用的做下次运算了  
        }
    }
    inline void polymul(ll *a,ll *b,ll *c,ll n,ll m)//计算多项式相乘 
    {
        ll len=1,w=0;
        while(len<=(n+m)) len<<=1,w++;
        cl(a,b,n,m,len,w);//这里的次数(w)不用加1因为两者都是同不改变的 
        ntt(tmp1,len,1);ntt(tmp2,len,1);
        for(int i=0;i<len;i++) c[i]=tmp1[i]*tmp2[i]%p; 
        ntt(c,len,-1);
    }
    inline void work()  //f=q*g+r  ask q,r     f,g下标从0--n,0--m 
    {
    
        reverse(f,f+1+n);//对应各式的反转操作 
        reverse(g,g+1+m);
    
        polyinv(g,inv,n-m+1);//求逆  因为反转后使r能够被忽略所以是在模x^(n-m+1)意义下的, 所以只要算出g在模x^(n-m+1)下的逆元 
        polymul(f,inv,q,n+1,n-m+1);//计算q 
    
        reverse(q,q+n-m+1);//将原式反转回来 
        reverse(f,f+n+1);
        reverse(g,g+m+1);
    
        polymul(g,q,r,m+1,n-m+1);//计算q*g的值 
        for(int i=0;i<m;i++) r[i]=(f[i]-r[i]+p)%p;//相减算出r 
    }
    int main()
    {
        n=read(),m=read();    //读入 
        for(int i=0;i<=n;i++) f[i]=read();
        for(int i=0;i<=m;i++) g[i]=read();
        work();
        for(int i=0;i<=n-m;i++) printf("%lld ",q[i]);printf("
    ");//输出 
        for(int i=0;i<m;i++)    printf("%lld ",r[i]);
        return 0;
    }
    多项式除法&取模

    线性基(2进制压位版)

    ll p[110];
    inline void xxj(ll x)//(算关于异或的)将数用2进制分解为  已有的组合(或可以凑出来的) 
    {
        for(ll i=63;i>=0;i--)
        {
            if(!(x>>(ll)i)) continue;
            if(!p[i])
            {
                p[i]=x;
                break;//return 1;取 
            }
            x^=p[i];
        }
        //return 0;不取 
    }
    线性基(2进制压位版)

    cdq分治(cdq套cdq实现)

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const int N=100010;
    int n,k;
    int ans[N],d[N];//ans[i]各维都小于i的数量  d[i]数量为i的个数有多少个 
    struct xin{
        int x,y,z;
        bool v;
        int *ans;
        bool operator==(const xin &a)const
        {
            return x==a.x&&y==a.y&&z==a.z;
        } 
    }a[N],b[N],c[N];
    inline bool pd(xin a,xin b)
    {
        return a.x<b.x||a.x==b.x&&a.y<b.y||a.x==b.x&&a.y==b.y&&a.z<b.z;
    } 
    inline void cdq2(int l,int r)
    {
        if(l==r) return;
        int mid=(l+r)>>1;
        cdq2(l,mid);cdq2(mid+1,r);
        for(int k=l,i=l,j=mid+1,tmp=0;k<=r;k++)
        {
            if((j>r||b[i].z<=b[j].z)&&i<=mid) c[k]=b[i++],tmp+=c[k].v;
            else
            {
                c[k]=b[j++];
                if(!c[k].v) *c[k].ans+=tmp;
            }
        }
        for(int i=l;i<=r;i++) b[i]=c[i];
    }
    inline void cdq(int l,int r)//可以一直套用在多维偏序 
    {
        if(l==r) return; 
        int mid=(l+r)>>1;
        cdq(l,mid);cdq(mid+1,r);
        for(int k=l,i=l,j=mid+1;k<=r;k++)
        {
            if((j>r||a[i].y<=a[j].y)&&i<=mid) b[k]=a[i++],b[k].v=1;
            else b[k]=a[j++],b[k].v=0; 
        }
        for(int i=l;i<=r;i++) a[i]=b[i];
        cdq2(l,r);
    }
    int main()
    {
        n=read(),k=read();
        for(int i=1;i<=n;i++){a[i].x=read(),a[i].y=read(),a[i].z=read(),a[i].ans=&ans[i];}
        sort(a+1,a+1+n,pd);
        for(int i=n-1;i;i--) 
        if(a[i]==a[i+1])//去重 
          *a[i].ans=*a[i+1].ans+1;
        cdq(1,n);
        for(int i=1;i<=n;i++) d[ans[i]]++;
        for(int i=0;i<n;i++) printf("%d
    ",d[i]);
        return 0;
    }
    cdq分治

    IO优化

    namespace IO
    {
        char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
        inline char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
        inline void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; }
        inline void Put(register char x) { *oS++=x; if(oS==oT) Flush(); }
        inline int read(){register int x=0;register char ch=Get();while(ch>57||ch<48)ch=Get();while(ch>=48&&ch<=57)x=x*10+(ch^48),ch=Get();return x;}
        inline void write(register int x) { register int top=0;if(!x)Put('0');while(x) st[++top]=(x%10)+48,x/=10; while(top) Put(st[top--]); Put(' '); }
        inline void print(register int x) { register int top=0;if(!x)Put('0');while(x) st[++top]=(x%10)+48,x/=10; while(top) Put(st[top--]); Put('
    '); }
    }
    using namespace IO;
    IO

    polya(环形的置换 只管旋转不管翻转版)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const ll p=1e9+7;
    ll n;
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    inline ll oula(ll n)
    {
        ll ans=n;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i) continue;
            ans=ans/i*(i-1);
            while(n%i==0) n/=i;
        }
        if(n>1) ans=ans/n*(n-1);
        return ans;
    } 
    inline ll polya(ll n,ll m)// n操作个数(链上是长度) m颜色数  求旋转不重复(不算翻转) 
    {
        ll ans=0;//环形的置换 只管旋转不管翻转 颜色不干扰无限制 
        for(int i=1;i*i<=n;i++)
        {
            if(n%i) continue;
            //ans=(for(ai,ai属于G)sum(k,ai循环节数)/n;
            //因为只有旋转 每个循环节长度lcm(n,i)/i  ai循环节数=n/(lcm(n,i)/i)=gcd(n,i) 
            //ans=(for(1,n)sum(ksm(k,gcd(n,i))/n;
            //ans=oula[i]*ksm(k,n/i)/n  (i属于n的约数) 
            ans=(ans+oula(i)*ksm(m,n/i)%p)*ny[n]%p;  //if(n==m) ans=ans+oula(i)*ksm(m,n/i-1)%p;
            if(i*i!=n) ans=(ans+oula(n/i)*ksm(m,i)%p)*ny[x]%p;  //if(n==m) ans=ans+oula(n/i)*ksm(m,i-1)%p;
        }
        return ans%p;
    }
    polya

    SG函数

    //【SG定理】
    //sg值为0必败否则必胜
    //一种方案的结束为子游戏的sg异或
    //不同方案sg为mex(sg[方案1],sg[方案s2]..)
    //【SJ定理】
    //对于任意一个Anti-SG游戏,如果定义所有子游戏SG值为0时游戏结束,先手必胜条件:
    //1. 游戏的SG值为0且所有子游戏的SG值均不超过1;
    //2. 游戏的SG值不为0且至少一个子游戏的SG值超过1。
    const int N=;
    int sg[N],mex[];//mex的大小看sg转移最大会取的数的范围 
    inline int getsg(int x)//记得初始化 sg=-1 和初始状态 
    {
        if(sg[x]!=-1) return sg[x];
        //  枚举状态 
        mj();
        //for(int i=1;i<x;i++)
        //for(int j=1;j<=i;j++)
        //  mex[getsg(i)^getsg(j)]=x;
        //  枚举状态 
        while(mex[sg[x]]==x) sg[x]++;//因为每种x要计算的只有一次 如果sg[x]会变的话就不能那么写 
        return sg[x];
    } 
    SG函数

    点分治

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    #define fi first
    #define se second
    #define mp make_pair
    const ll N=1e5+10;
    ll n,p;
    ll rt,ans,sum,topd;
    ll ml[N];
    ll sz[N],ch[N],vis[N];
    map<ll,ll>s;
    pair<ll,ll>dig[N<<1];
    ll link[N],e[N<<1],nxt[N<<1],v[N<<1],top;
    inline void into(ll xx,ll yy,ll vv)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top,v[top]=vv;
    }
    inline ll exgcd(ll a,ll b,ll& x,ll& y) {
        if(!b){ x=1,y=0; return a; }
        ll d=exgcd(b,a%b,x,y);
        ll z=x; x=y; y=z-a/b*y;
        return d;
    }
    inline ll ny(ll a,ll m) { //a在mod m意义下的逆元
        ll x,y,d=exgcd(a,m,x,y);
        return d==1?(x%m+m)%m:-1;
    }
    inline void gm(ll x,ll fa)//找树重心 
    {
        sz[x]=1;ch[x]=0;
        for(ll i=link[x];i;i=nxt[i])
        {
            ll u=e[i];
            if(u==fa||vis[u]) continue;
            gm(u,x);
            sz[x]+=sz[u];
            ch[x]=max(ch[x],sz[u]);
        }
        ch[x]=max(ch[x],sum-ch[x]);
        if(ch[x]<ch[rt]) rt=x;
    }
    inline void gd(ll x,ll fa,ll d1,ll d2,ll d)
    {
        if(d>=0) s[d1]++,dig[++topd]=mp(d2,d);
        for(ll i=link[x];i;i=nxt[i])
        {
            ll u=e[i],z=v[i];
            if(u==fa||vis[u]) continue;
            ll d3=(d1+z*ml[d+1])%p;
            ll d4=(d2*10+z)%p;
            gd(u,x,d3,d4,d+1);
        }
    }
    inline ll js(ll x,ll d)
    {
        s.clear();ll rt=0;topd=0;
        if(d) gd(x,0,d%p,d%p,0);
        else gd(x,0,0,0,-1);
        for(ll i=1;i<=topd;i++)
        {
            ll tmp=(-dig[i].fi*ny(ml[dig[i].se+1],p)%p+p)%p;
            if(s.find(tmp)!=s.end()) rt+=s[tmp];
            if(!d) rt+=!dig[i].fi;
        }
        if(!d) rt+=s[0];
        return rt;
    }
    inline void solve(ll x)
    {
        ans+=js(x,0);vis[x]=1;
        for(ll i=link[x];i;i=nxt[i])
        {
            ll u=e[i],z=v[i];
            if(vis[u]) continue;
            ans-=js(u,z);
            sum=sz[u],ch[0]=n,rt=0;
            gm(u,x);
            solve(rt);
        }
    }
    int main()//题目Digit Tree 
    {
        n=read(),p=read();
        for(ll i=1;i<n;i++)
        {
            ll x=read()+1,y=read()+1,v=read();
            into(x,y,v);into(y,x,v);
        } 
        ml[0]=1;
        for(ll i=1;i<=n;i++) ml[i]=((ml[i-1]<<3)+(ml[i-1]<<1))%p;
        ch[0]=sum=n;gm(1,0);
        solve(rt);
        cout<<ans; 
        return 0;
    }
    点分治

    求oula(sqrt(n)暴力)

    inline ll oula(ll n)
    {
        ll ans=n;
        for(int i=2;i*i<=n;i++)
        {
            if(n%i) continue;
            ans=ans/i*(i-1);
            while(n%i==0) n/=i;
        }
        if(n>1) ans=ans/n*(n-1);
        return ans;
    }
    求oula

    数论分块

    const ll p=;
    ll slfk(ll x,ll y) //for(d,1,n)sum((n/d)(m/d)) 
    {
        ll ans=0,tmp;
        for(int i=1;i<=min(x,y);i=tmp+1)
        {
            tmp=min(x/(x/i),y/(y/i));
            ans=(ans+/**/1ll*(tmp-i+1)*(i+tmp)/2/**/%p*work(n/i,m/i)%p)%p;
        }//              前缀和函数              内套函数 
         //             这里写的是等差数列的  
        return ans;
    }
    数论分块

    线段树分治

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    #define fi first
    #define se second
    #define pb push_back
    #define mid ((l+r)>>1)
    #define lsn x<<1 
    #define rsn x<<1|1
    const int N=5e5+10; 
    int n,m,t,now,ans[N]; 
    int topp,topq,topk;
    int fa[N],sz[N],v[N],sk[N];
    struct xin{
        int x,y,v; 
    };
    bool operator < (xin a,xin b)
    {
        if(a.x!=b.x)return a.x<b.x;
        return a.y<b.y;
    }
    map<xin,int>s;
    map<xin,int>::iterator it;
    struct xin2{
        xin s;
        int l,r;
    }p[N<<1];
    struct xin3{
        int x,y,id;
    }q[N<<1];
    vector<xin>tr[N<<2];
    inline int gfa(int a)
    {
        return fa[a]==a?a:gfa(fa[a]);
    }
    inline int gv(int a)
    {
        return fa[a]==a?0:gv(fa[a])^v[a]; 
    }
    inline bool merge(xin s)
    {
        int a=s.x,b=s.y,afa=gfa(a),bfa=gfa(b);
        if(afa==bfa) return 0;
        if(sz[afa]>sz[bfa]) swap(afa,bfa),swap(a,b);
        v[afa]=gv(a)^gv(b)^s.v;
        fa[afa]=bfa;sz[bfa]+=sz[afa];sk[++topk]=afa;
        return 1;
    }
    inline void erase()
    {
        int a=sk[topk--];
        sz[fa[a]]-=sz[a];fa[a]=a;v[a]=0;
    }
    struct base{
        int s[33];
        inline void insert(int x)
        {
            for(int i=31;i>=0;i--) if(1<<i&x)
            {
                if(!s[i]){s[i]=x;break;}
                else x^=s[i];
            }
        }
        inline int ask(int x)
        {
            for(int i=31;i>=0;i--) if(1<<i&x) x^=s[i];
            return x;
        }
    }sp[200];
    inline void add(int x,int l,int r,int ql,int qr,xin s)
    {
        if(ql<=l&&r<=qr){tr[x].pb(s);return;}
        if(ql<=mid) add(lsn,l,mid,ql,qr,s);
        if(mid<qr) add(rsn,mid+1,r,ql,qr,s);
    }
    inline void ask(int x,int l,int r,int cs)
    {
        if(l>r) return;
        int tm=0,len=tr[x].size();
        for(int i=0;i<len;i++)
        {
            if(merge(tr[x][i])) tm++;
            else sp[cs].insert(gv(tr[x][i].x)^gv(tr[x][i].y)^tr[x][i].v);
        } 
        if(l==r)
        {
            while(now<topq&&q[now+1].id==l)
            {
                now++;
                ans[q[now].id]=sp[cs].ask(gv(q[now].x)^gv(q[now].y));
            }
        }
        else
        {
            for(int i=31;i>=0;i--) sp[cs+1].s[i]=sp[cs].s[i];ask(lsn,l,mid,cs+1);
            for(int i=31;i>=0;i--) sp[cs+1].s[i]=sp[cs].s[i];ask(rsn,mid+1,r,cs+1); 
        }
        for(int i=0;i<tm;i++) erase();
    }
    int main()//加边 删边 询问最小异或和  题目:CF938G Shortest Path Queries  
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            xin x;x.x=read(),x.y=read(),x.v=read();
            if(x.x>x.y) swap(x.x,x.y);
            s.insert(pair<xin,int>(x,0));
        }
        t=read();
        for(int i=1;i<=t;i++)
        {
            int pd=read();
            if(pd==1)// 
            {
                xin x;x.x=read(),x.y=read(),x.v=read();
                if(x.x>x.y) swap(x.x,x.y);
                s.insert(pair<xin,int>(x,i)); 
            }
            if(pd==2)
            {
                xin x;x.x=read(),x.y=read();
                it=s.find(x);
                p[++topp]=(xin2){it->fi,it->se,i};
                s.erase(it);
            }
            if(pd==3)
            {
                q[++topq].id=i;q[topq].x=read(),q[topq].y=read();
                if(q[topq].x>q[topq].y) swap(q[topq].x,q[topq].y);
            }
        }
        for(it=s.begin();it!=s.end();it++) p[++topp]=(xin2){it->fi,it->se,m};
        for(int i=1;i<=topp;i++) add(1,0,t,p[i].l,p[i].r,p[i].s); 
        for(int i=1;i<=n;i++) fa[i]=i,sz[i]=1,v[i]=0;
        ask(1,0,m,1);
        for(int i=1;i<=topq;i++) printf("%d
    ",ans[q[i].id]);
        return 0;
    }
    线段树分治

    线性推逆元

    const int N=;
    const ll p=;
    int ny[N];
    int mian()
    {
        ny[1]=1;
        for(int i=2;i<p;++i)
        ny[i]=(p-p/i)*ny[p%i]%p;
        return 0;
    }
    线性推逆元

    主席树

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const int N=2e5+10;//注意改范围 
    int n,m; 
    int q,topx;
    int a[N],b[N],rt[N];//rt根节点 
    struct xin{
        int l,r,v;
    }tr[N<<5]; //建权值线段树   注意看看是否会MLE 
    inline void build(int &x,int l,int r)
    {
        x=++topx;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(tr[x].l,l,mid);build(tr[x].r,mid+1,r); 
    }
    inline int add(int x,int l,int r,int w)
    {
        int xx=++topx;
        tr[xx].l=tr[x].l;tr[xx].r=tr[x].r;tr[xx].v=tr[x].v+1;
        if(l==r) return xx;
        int mid=(l+r)>>1;
        if(w<=mid) tr[xx].l=add(tr[xx].l,l,mid);
        else  tr[xx].r=add(tr[xx].r,mid+1,r);
        return xx;
    }
    inline int ask(int x,int y,int l,int r,int k)//求第k小 
    {
        int mid=(l+r)>>1,ans=-1,c=tr[tr[y].l].v-tr[tr[x].l].v;
        if(l==r) return l;
        if(c>=k) ans=ask(tr[x].l,tr[y].l,l,mid,k);
        else ans=ask(tr[x].r,tr[y].r,mid+1,r,k-c);
        return ans; 
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++) a[i]=b[i]=read();
        sort(b+1,b+1+n);
        q=unique(b+1,b+1+n)-b-1;
        build(rt[0],1,q);
        for(int i=1;i<=n;i++)
        {
            int w=lower_bound(b+1,b+1+q,a[i])-b;
            rt[i]=add(rt[i-1],1,q,w);
        }
        for(int i=1;i<=m;i++)
        {
            int l=read(),r=read(),k=read();
            printf("%d
    ",b[ask(rt[l-1],rt[r],1,q,k)]);
        }
        return 0;
    }
    主席树

    类欧

    const ll p=998244353;
    const ll ny2=499122177;
    const ll ny6=166374059;
    struct xin {
        ll f,g,h;//base i*base base*base
    };
    xin smgcd(ll a,ll b,ll c,ll n){
        xin ans,tmp;
        if(a==0){
            ans.f=(n+1)*(b/c)%p;
            ans.g=(b/c)*n%p*(n+1)%p*ny2%p;
            ans.h=(n+1)*(b/c)%p*(b/c)%p;
            return ans;
        }
        if(a>=c||b>=c){
            tmp=smgcd(a%c,b%c,c,n);
            ans.f=(tmp.f+(a/c)*n%p*(n+1)%p*ny2%p+(b/c)*(n+1)%p)%p;
            ans.g=(tmp.g+(a/c)*n%p*(n+1)%p*(2*n+1)%p*ny6%p+(b/c)*n%p*(n+1)%p*ny2%p)%p;
            ans.h=((a/c)*(a/c)%p*n%p*(n+1)%p*(2*n+1)%p*ny6%p+
                   (b/c)*(b/c)%p*(n+1)%p+(a/c)*(b/c)%p*n%p*(n+1)%p+
                    tmp.h+2*(a/c)%p*tmp.g%p+2*(b/c)%p*tmp.f%p)%p;
            return ans;
        }
        ll m=(a*n+b)/ c;
        tmp=smgcd(c,c-b-1,a,m-1);
        ans.f=(n*(m%p)%p-tmp.f)%p;
        ans.g=(n*(n+1)%p*(m%p)%p-tmp.f-tmp.h)%p*ny2%p;
        ans.h=(n*(m%p)%p*((m+1)%p)%p-2*tmp.g-2*tmp.f-ans.f)%p;
        return ans;
    }
    类欧

    矩阵求逆

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const ll N=410,p=1e9+7;
    ll n; 
    struct xin{
        ll a[N][N];
        //inline int* operator [](int x){return a[x];} //  b的话直接调用b[][] 
        inline void swap(int x,int y){for(int i=1;i<=n;i++) swap(a[x][i],a[y][i]);}
        inline void mul(int x,int k){for(int i=1;i<=n;i++) a[x][i]=(a[x][i]*k%p+p)%p;}//a[x]=k*a[y];
        inline void add(int x,int y,int k){for(int i=1;i<=n;i++) a[x][i]=((a[x][i]+a[y][i]*k)%p+p)%p;}// a[x]加k*a[y] 
        inline void prt()
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++) printf("%lld ",a[i][j]);
                printf("
    ");
            }
        }
    }a,b;
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    }
    void gaosi()
    {
        for(int i=1;i<=n;i++)
        {
            if(!a.a[i][i]) for(int j=i+1;j<=n;j++) if(a.a[j][i])
            {
                a.swap(i,j);b.swap(i,j);
                break;
            }
            if(!a.a[i][i]){printf("No Solution
    ");exit(0);} 
            b.mul(i,ksm(a.a[i][i],p-2));a.mul(i,ksm(a.a[i][i],p-2));//把所有项除a[i][i] 变成a[i][i]变成1 
            for(int j=1;j<=n;j++)
            {
                if(i==j) continue; 
                b.add(j,i,-a.a[j][i]);a.add(j,i,-a.a[j][i]);//消去  b要放前面因为a放前面会被修改 
            }
        }
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          a.a[i][j]=read();
        for(int i=1;i<=n;i++) b.a[i][i]=1;
        gaosi();
        b.prt();
        return 0;
    }
    /*
    如果矩阵有逆
    
    那么这个矩阵经过一系列初等变化之后可以变为E
    
    设一系列初等变化分别为p1,p2,p3...px
    
    显然可得A*p1*p2*p3*...*px=E
    
    所以B=p1*p2*p3*...*px
    
    这样的话就很好做了
    
    我们利用高斯消元来让A逐渐变为单位矩阵
    
    设B初始为E
    
    B也跟着A同步变换
    
    那么到A变为单位矩阵时 B也就是p1*p2*p3*...*px的值了
    
    矩阵无逆的情况显然是高斯消元无法再消(a[1][i]-a[n][i]都为0时)特判输出就行哩
    */ 
    矩阵求逆

    常系数齐次递推

     #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const int p=998244353,G=3,N=140010;
    int n,k,mx,cs,qvq,tz;
    ll rev[N];
    ll f[N],st[N],g[N],invg[N];
    ll tmp[N],tmp1[N],tmp2[N],tmpa[N],tmpb[N];
    ll a[N],ans[N];
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%p;
            a=(a*a)%p;
            b>>=1;
        }
        return ans;
    } 
    inline void ntt(ll *a,ll n,ll kd)
    {
        for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
        for(int i=1;i<n;i<<=1)
        {
            ll gn=ksm(G,(p-1)/(i<<1));
            for(int j=0;j<n;j+=(i<<1))
            {
                ll t1,t2,g=1;
                for(int k=0;k<i;k++,g=g*gn%p)
                {
                    t1=a[j+k],t2=g*a[j+k+i]%p;
                    a[j+k]=(t1+t2)%p,a[j+k+i]=(t1-t2+p)%p;
                } 
            }
        }
        if(kd==1) return;
        ll ny=ksm(n,p-2);
        reverse(a+1,a+n);
        for(int i=0;i<n;i++) a[i]=a[i]*ny%p;
    } 
    inline void cl(ll *a,ll *b,ll n,ll m,ll len,ll w)
    {
        for(int i=0;i<len;i++) tmp1[i]=i<n?a[i]:0;
        for(int i=0;i<len;i++) tmp2[i]=i<m?b[i]:0;
        for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(w-1));
    }
    inline void polyinv(ll *a,ll *b,ll ed)
    {
        b[0]=ksm(a[0],p-2);
        for(int k=1,j=0;k<=(ed<<1);k<<=1,j++)
        {
            ll len=k<<1;
            cl(a,b,k,k,len,j+1);
            ntt(tmp1,len,1);ntt(tmp2,len,1);
            for(int i=0;i<len;i++) b[i]=tmp2[i]*(2ll-tmp1[i]*tmp2[i]%p+p)%p;
            ntt(b,len,-1);
            for(int i=k;i<len;i++) b[i]=0;
        }
    }
    inline void polymul(ll *a,ll *b,ll *c,ll n,ll m)
    {
        ll len=1,w=0;
        while(len<=(n+m)) len<<=1,w++;
        cl(a,b,n,m,len,w);
        ntt(tmp1,len,1);ntt(tmp2,len,1);
        for(int i=0;i<len;i++) c[i]=tmp1[i]*tmp2[i]%p;
        ntt(c,len,-1);
    }
    inline void polymod(ll *a,ll n=mx<<1,ll m=k)
    {                   
        int ed=(mx<<1);while(a[--ed]==0);if(ed<k) return; 
        
        n=ed;
        reverse(a,a+1+n);
        polymul(a,invg,tmpa,n+1,n-m+1);    
        reverse(tmpa,tmpa+n-m+1);
        reverse(a,a+1+n);
        
        polymul(g,tmpa,tmpb,m+1,n-m+1);
        for(int i=0;i<k;i++) a[i]=(a[i]-tmpb[i]+p)%p;
        for(int i=k;i<=ed;i++)a[i]=0;
        for(int i=0;i<(mx<<1);i++) tmpa[i]=tmpb[i]=0;
    }
    int main()
    {
        freopen("testdata.in","r",stdin);
        freopen("testdata.out","w",stdout);
        n=read(),k=read();mx=1,cs=0;
        while(mx<=k) mx<<=1,cs++;
        for(int i=1;i<=k;i++) f[i]=read(),f[i]=f[i]<0?f[i]+p:f[i];
        for(int i=0;i<k;i++) st[i]=read(),st[i]=st[i]<0?st[i]+p:st[i];
        for(int i=1;i<=k;i++) g[k-i]=p-f[i];g[k]=1;
        for(int i=0;i<=k;i++) tmp[i]=g[i];
        
        reverse(tmp,tmp+1+k);
        polyinv(tmp,invg,mx);
        for(int i=mx;i<=(mx<<1);i++) invg[i]=0;
        for(int i=0;i<=k;i++) tmp[i]=0;
        for(int i=0;i<(mx<<1);i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(cs+1-1));
        ans[0]=1;a[1]=1;
        while(n)
        {
            if(n&1){polymul(ans,a,ans,k,k);polymod(ans);}
            polymul(a,a,a,k,k);polymod(a);
            n>>=1;
        }
        for(int i=0;i<k;i++) qvq=(qvq+ans[i]*st[i])%p;
        cout<<qvq; 
        return 0;
    }
    常系数齐次递推(常数巨大版)

    tarjan割点

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=1e5+10;
    int n,m,gs; 
    int dfn[N],low[N],topn,cut[N];
    int link[N],e[N<<1],nxt[N<<1],top;
    inline void into(int xx,int yy)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top;
    }
    inline void tarjan(int x,int rt)
    {
        dfn[x]=low[x]=++topn;int flag=0;
        for(int i=link[x];i;i=nxt[i])
        {
            int u=e[i];
            if(dfn[u]){low[x]=min(low[x],dfn[u]);continue;}
            tarjan(u,rt);
            low[x]=min(low[x],low[u]);
            if(low[u]>=dfn[x])
            {
                flag++;
                if(x!=rt||flag>1) cut[x]=1;
            }
        }
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            if(x==y) continue;
            into(x,y);into(y,x);
        }
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,i);
        for(int i=1;i<=n;i++) if(cut[i]) gs++;
        cout<<gs<<endl;
        for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i);
        return 0;
    }
    tarjan割点

    笛卡尔树建树

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const ll N=510,p=1000000007,Y=1e6+10;
    ll n,k,a[N];
    ll jc[Y],ny[Y],dp[N][N],tmp[N];
    ll topq,topt,topd;
    ll vx[N],vy[N];
    ll link[N],nxt[N<<1],e[N<<1],top;
    inline void into(ll xx,ll yy)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top; 
    }
    struct xin{
        ll l,r,h,d,pd;
        bool operator == (const xin &b)
        {
            return l==b.l&&r==b.r&&h==b.h&&d==b.d&&pd==b.pd;
        }
    }q[N],tp[N];
    inline ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%p;
            a=a*a%p; 
            b>>=1;
        }
        return ans;
    }
    inline ll js(ll x,ll y,ll v)
    {
        return (jc[x]*ny[x-v]%p*ny[v]%p)*jc[y]%p*ny[y-v]%p;
    }
    inline void dfs(ll x,ll fa)
    {
        ll mn=min(k,vx[x]);
        if(x==topd) mn=k;
        dp[x][0]=1;
        for(ll i=link[x];i;i=nxt[i])
        {
            ll u=e[i];
            if(u==fa) continue;
            dfs(u,x);
            for(ll k=mn;k>=0;k--) tmp[k]=dp[x][k],dp[x][k]=0;
            for(ll k=mn;k>=0;k--) for(ll o=k;o>=0;o--) dp[x][k]=(dp[x][k]+tmp[k-o]*dp[u][o])%p;
        }
        if(x==topd) return;
        for(ll k=mn;k>=0;k--) tmp[k]=dp[x][k],dp[x][k]=0;
        for(ll k=mn;k>=0;k--) for(ll o=k;o>=0;o--) dp[x][k]=(dp[x][k]+tmp[k-o]*js(vx[x]-(k-o),vy[x],o))%p;
    }
    int main()//SP3734 PERIODNI - Periodni
    {
        n=read(),k=read();q[0].h=-1;tp[0].d=-1;
        jc[0]=ny[0]=1;
        for(ll i=1;i<=Y-10;i++) jc[i]=jc[i-1]*i%p; 
        ny[Y-10]=ksm(jc[Y-10],p-2);
        for(ll i=Y-10-1;i;i--) ny[i]=ny[i+1]*(i+1)%p;
        
        for(ll i=1;i<=n;i++) a[i]=read();a[n+1]=0;
        for(ll i=1;i<=n+1;i++)//////建树 st 
        {
            ll g=a[i],qm=i;
            while(q[topq].h>g)
            {
                topd++;qm=min(qm,q[topq].l);
                q[topq].d=max(q[topq-1].h,g);
                q[topq].pd=topd;
                q[topq].r=i-1;
                while(tp[topt].d>q[topq].d)
                {
                    into(topd,tp[topt].pd);
                    into(tp[topt].pd,topd);
                    topt--;
                }
                vx[topd]=q[topq].r-q[topq].l+1;
                vy[topd]=q[topq].h-q[topq].d;
                tp[++topt]=q[topq];
                topq--;
            }
            if(q[topq].h==g) q[topq].r=i;
            else{q[++topq].h=g;q[topq].l=qm;}
        }
        topd++; 
        while(topt)
        {
            into(topd,tp[topt].pd);
            into(tp[topt].pd,topd);
            topt--;
        }////////////////////////////建树ed 
        dfs(topd,0);
        cout<<dp[topd][k];
        return 0;
    }
    自己瞎yy的超鸡复杂的笛卡尔树建树

    高次求和

    for(1--n) sum+=i===========n*(n+1)/2;
    for(1--n) sum+=i*i=========n*(n+1)*(2n+1)/6 
    for(1--n) sum+=i*i*i=======n*n*(n+1)*(n+1)/4
    高次求和

    连续区间异或k大和

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    #define R register
    const ll N=20000000+10;
    ll n,k,ans;
    ll a[N],sum[N],sz[N];
    ll tr[N][2],top;
    struct xin{
        ll w,cs,v;
        friend bool operator < (xin a,xin b)
        {
            return a.v<b.v;
        }
    };
    priority_queue<xin>q;
    inline void into(ll v)
    {
        int u=0;
        for(int i=31;i>=0;i--)
        {
            ll tmp=(v>>i)&1;sz[u]++;
            if(!tr[u][tmp]) tr[u][tmp]=++top;
            u=tr[u][tmp];
        }
        sz[u]++;
    }
    inline ll ask(ll v,int cs)
    {
        ll u=0,ans=0;
        for(int i=31;i>=0;i--)
        {
            ll tmp=(v>>i)&1;
            if(!tr[u][tmp^1]){u=tr[u][tmp];continue;}
            if(cs<=sz[tr[u][tmp^1]]){u=tr[u][tmp^1];ans|=1LL<<i;continue;}
            if(cs>sz[tr[u][tmp^1]]){cs-=sz[tr[u][tmp^1]];u=tr[u][tmp];continue;}
        }
        return ans;
    }
    int main()
    {
        freopen("xor.in","r",stdin);
        freopen("xor.out","w",stdout); 
        n=read();k=read();k<<=1;
        for(R int i=1;i<=n;i++) a[i]=read();
        for(R int i=1;i<=n;i++) sum[i]=sum[i-1]^a[i];
        for(int i=0;i<=n;i++) into(sum[i]);
        for(int i=0;i<=n;i++) q.push((xin){i,1,ask(sum[i],1)});
        for(int i=1;i<=k;i++)
        {
            xin tmp=q.top();q.pop();ans+=tmp.v;
            if(tmp.cs<n) q.push((xin){tmp.w,tmp.cs+1,ask(sum[tmp.w],tmp.cs+1)});
        }
        cout<<(ans>>1)<<endl;
        return 0;
    }
    连续区间异或k大和

    扫描线

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const ll N=200000+10;
    ll n,m,topb;
    ll ans; 
    ll id[N],ed[N],topi;
    ll link[N],nxt[N<<1],e[N<<1],top;
    inline void into(ll xx,ll yy)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top;
    }
    inline void dfs(ll x,ll fa)
    {
        id[x]=++topi;
        for(ll i=link[x];i;i=nxt[i])
        {
            ll u=e[i];
            if(u==fa) continue;
            dfs(u,x); 
        }
        ed[x]=topi;
    }
    struct xin{
        ll a1,a2,b,v;
    }a[N<<2],b[N<<2];
    inline bool pd(xin a,xin b)
    {
        return a.b<b.b||(a.b==b.b&&a.v>b.v);
    }
    inline bool pd2(xin a,xin b)
    {
        return a.a1<b.a1||(a.a1==b.a1&&a.a2<b.a2);
    }
    struct xin2{
        ll v,del;
    }tr[N<<3];
    inline void up(ll x,ll l,ll r)
    {
        if(tr[x].del>0) tr[x].v=(r-l+1);
        else tr[x].v=tr[x<<1].v+tr[x<<1|1].v;
    }
    inline void add(ll x,ll l,ll r,ll ql,ll qr,ll v)
    {
        if(ql<=l&&r<=qr)
        {
            tr[x].del+=v;
            if(tr[x].del>0) tr[x].v=r-l+1;
            else tr[x].v=tr[x<<1].v+tr[x<<1|1].v;
            return;
        }
        ll mid=(l+r)>>1;
        if(ql<=mid) add(x<<1,l,mid,ql,qr,v);
        if(mid+1<=qr) add(x<<1|1,mid+1,r,ql,qr,v);
        up(x,l,r);
    }
    inline ll ask(ll x,ll l,ll r,ll ql,ll qr)
    {
        if(ql<=l&&r<=qr){return tr[x].v;}
        ll mid=(l+r)>>1;
        ll ans=0;
        if(ql<=mid) ans=ans+ask(x<<1,l,mid,ql,qr);
        if(mid+1<=qr) ans=ans+ask(x<<1|1,mid+1,r,ql,qr);
        return ans;
    }
    int main()
    {
        freopen("jasmine.in","r",stdin);
        freopen("jasmine.out","w",stdout); 
        n=read(),m=read();ans=n*n;
        for(ll i=2;i<=n;i++)
        {
            ll x=read();
            into(x,i);into(i,x);
        } 
        dfs(1,0); 
        for(ll i=1;i<=m;i++)
        {
            ll x=read(),y=read();
            a[i]=(xin){id[x],ed[x],id[y],1};
            a[i+m]=(xin){id[x],ed[x],ed[y]+1,-1}; 
            a[i+2*m]=(xin){id[y],ed[y],id[x],1};
            a[i+3*m]=(xin){id[y],ed[y],ed[x]+1,-1}; 
        }
        sort(a+1,a+1+4*m,pd);
        ll qw=a[1].b,qv=0;
        for(ll i=1;i<=4*m;i++)
        {
            ll l=a[i].a1,r=a[i].a2,w=a[i].b,v=a[i].v;
            ans-=qv*(w-qw);
            qw=w;add(1,1,n,l,r,v);qv=ask(1,1,n,1,n);
        }
        cout<<ans;
        return 0;
    }
    扫描线

    树剖

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const ll N=1e5+10;
    ll n,m,r,p;
    int a[N];
    int fa[30][N],deep[N],sz[N],sn[N];
    int id[N],topi,bs[N],topw[N];
    int link[N],nxt[N<<1],e[N<<1],top;
    inline void into(int xx,int yy)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top;
    }
    inline void dfs1(int x)
    {
        int mxsn=-1;sz[x]=1;
        for(int i=link[x];i;i=nxt[i])
        {
            int u=e[i];
            if(u==fa[0][x]) continue;
            deep[u]=deep[x]+1;fa[0][u]=x;
            dfs1(u);
            sz[x]+=sz[u];
            if(sz[u]>mxsn){mxsn=sz[u],sn[x]=u;}
        }
    }
    inline void dfs2(int x,int tp)
    {
        id[x]=++topi;bs[topi]=a[x];topw[x]=tp;
        if(!sn[x]) return;
        dfs2(sn[x],tp);
        for(int i=link[x];i;i=nxt[i])
        {
            int u=e[i];
            if(u==fa[0][x]||u==sn[x]) continue;
            dfs2(u,u);
        }
    }
    struct xin{
        ll v,del;
    }tr[N<<2];
    inline void up(int x)
    {
        tr[x].v=(tr[x<<1].v+tr[x<<1|1].v)%p;
    }
    inline void down(int x,int l,int r,int mid)
    {
        tr[x<<1].v=(tr[x<<1].v+(mid-l+1)*tr[x].del)%p;
        tr[x<<1].del=(tr[x<<1].del+tr[x].del)%p;
        tr[x<<1|1].v=(tr[x<<1|1].v+(r-(mid+1)+1)*tr[x].del)%p;
        tr[x<<1|1].del=(tr[x<<1|1].del+tr[x].del)%p;
        tr[x].del=0;
    }
    inline void build(int x,int l,int r)
    {
        if(l==r){tr[x].v=bs[l];return;}
        int mid=(l+r)>>1;
        build(x<<1,l,mid);build(x<<1|1,mid+1,r);
        up(x);
    }
    inline void add(int x,int l,int r,int ql,int qr,int v)
    {
        if(ql<=l&&r<=qr){tr[x].v=(tr[x].v+(r-l+1)*v)%p;tr[x].del=(tr[x].del+v)%p;return;}
        int mid=(l+r)>>1;
        down(x,l,r,mid);
        if(ql<=mid) add(x<<1,l,mid,ql,qr,v);
        if(mid+1<=qr) add(x<<1|1,mid+1,r,ql,qr,v);
        up(x);
    }
    inline ll ask(int x,int l,int r,int ql,int qr)
    {
        if(ql<=l&&r<=qr){return tr[x].v;}
        int mid=(l+r)>>1;
        ll ans=0;
        down(x,l,r,mid);
        if(ql<=mid) ans=(ans+ask(x<<1,l,mid,ql,qr))%p;
        if(mid+1<=qr) ans=(ans+ask(x<<1|1,mid+1,r,ql,qr))%p;
        return ans;
    }
    inline void addl(int a,int b,int v)
    {
        while(topw[a]!=topw[b])
        {
            if(deep[topw[a]]<deep[topw[b]]) swap(a,b);
            add(1,1,n,id[topw[a]],id[a],v);
            a=fa[0][topw[a]];
        }
        if(deep[a]>deep[b]) swap(a,b);
        add(1,1,n,id[a],id[b],v);
    }
    inline ll askl(int a,int b)
    {
        ll ans=0;
        while(topw[a]!=topw[b])
        {
            if(deep[topw[a]]<deep[topw[b]]) swap(a,b);
            ans=(ans+ask(1,1,n,id[topw[a]],id[a]))%p;
            a=fa[0][topw[a]];
        }
        if(deep[a]>deep[b]) swap(a,b);
        ans=(ans+ask(1,1,n,id[a],id[b]))%p;
        return ans;
    }
    inline void adds(int x,int v)
    {
        add(1,1,n,id[x],id[x]+sz[x]-1,v);
    }
    inline ll asks(int x)
    {
        return ask(1,1,n,id[x],id[x]+sz[x]-1);
    }
    int main()
    {
        n=read();m=read(),r=read(),p=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<n;i++)
        {
            int x=read(),y=read();
            into(x,y);into(y,x);
        }
        fa[0][r]=0,deep[r]=1;
        dfs1(r);dfs2(r,r);build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int pd=read();
            if(pd==1) 
            {
                int x=read(),y=read(),v=read();
                addl(x,y,v);
            }
            if(pd==2)
            {
                int x=read(),y=read();
                printf("%lld
    ",askl(x,y));
            }
            if(pd==3)
            {
                int x=read(),v=read();
                adds(x,v);
            }
            if(pd==4)
            {
                int x=read();
                printf("%lld
    ",asks(x));
            }
        }
        return 0;
    }
    树剖

    Dinic

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    } 
    const int N=2e5+10,inf=1e9; 
    int n,m,st,ed;
    int mxflow;
    queue<int>q;
    int arc[N],deep[N];
    int link[N],e[N<<1],nxt[N<<1],v[N<<1],top;
    inline void into(int xx,int yy,int vv)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top,v[top]=vv;
    }
    inline bool spfa(int st,int ed)
    {
        for(int i=1;i<=n;i++) deep[i]=inf;
        for(int i=1;i<=n;i++) arc[i]=link[i];
        while(!q.empty()) q.pop();
        deep[st]=1;q.push(st);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=link[x];i;i=nxt[i])
            {
                int u=e[i];
                if(deep[u]!=inf||(!v[i])) continue;
                deep[u]=deep[x]+1;q.push(u);
            }
        } 
        return deep[ed]!=inf;
    }
    inline int dfs(int x,int ed,int limit)
    {
        if((!limit)||x==ed) return limit;
        int flow=0;
        for(int i=arc[x];i;i=nxt[i])
        {
            int u=e[i];arc[x]=i;
            if(deep[u]!=deep[x]+1) continue;
            int tmp=dfs(u,ed,min(limit,v[i]));
            if(tmp)
            {
                flow+=tmp;limit-=tmp;
                v[i]-=tmp;v[(i&1)?(i+1):(i-1)]+=tmp;
                if(!limit) break;
            }
        }
        return flow;
    }
    void dinic(int st,int ed)
    {
        while(spfa(st,ed)) mxflow+=dfs(st,ed,inf);
    }
    int main()//Dinic VVE nnm 
    {
        int t1=clock();
        freopen("1.in","r",stdin);
        n=read(),m=read(),st=read(),ed=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),v=read();
            into(x,y,v);into(y,x,0); 
        }
        dinic(st,ed);cout<<clock()-t1<<endl;
        cout<<mxflow;
        return 0;
    }
    Dinic

    Edmond-Karp

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=210,inf=1e9;
    int n,m,ans;
    queue<int>q;
    int a[N][N],pre[N],flow[N];
    inline int spfa(int st,int ed)
    {
        while(!q.empty()) q.pop();
        for(int i=1;i<=n;i++) pre[i]=0;
        flow[st]=inf;pre[st]=st;
        q.push(st);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            if(x==ed) break;
            for(int i=1;i<=n;i++) 
            {
                int u=i;
                if(a[x][u]<=0||pre[u]) continue;
                pre[u]=x;flow[u]=min(flow[x],a[x][u]);
                q.push(u);
            }
        }
        if(!pre[ed]) return 0;
        return flow[ed];
    }
    void ek(int st,int ed)
    {
        int del=0;
        while((del=spfa(st,ed)))
        {
            int dq=ed;
            while(dq!=st)
            {
                int qm=pre[dq];
                a[qm][dq]-=del;
                a[dq][qm]+=del;
                dq=qm;
            }
            ans+=del;
        }
    }
    int main()//EK VEE nmm
    {
        m=read(),n=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),v=read();
            a[x][y]+=v;
        }
        ek(1,n);
        cout<<ans;
        return 0;
    }
    Edmond-Karp

    EK_费用流

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=50000+10,inf=1e9; 
    int n,m,st,ed;
    int mxflow,mncos;
    queue<int>q;
    int vis[N],cost[N],flow[N],pre[N],qmb[N];
    int link[N],e[N<<1],nxt[N<<1],v[N<<1],bs[N<<1],top;
    inline void into(int xx,int yy,int vv,int bsbs)
    {
        e[++top]=yy,nxt[top]=link[xx],link[xx]=top,v[top]=vv,bs[top]=bsbs;
    }
    inline bool spfa(int st,int ed)
    {
        for(int i=1;i<=n;i++) cost[i]=inf;
        for(int i=1;i<=n;i++) flow[i]=inf;
        for(int i=1;i<=n;i++) vis[i]=0;
        while(!q.empty()) q.pop();
        q.push(st);vis[st]=1;cost[st]=0;pre[ed]=0;
        while(!q.empty())
        {
            int x=q.front();q.pop();vis[x]=0;
            for(int i=link[x];i;i=nxt[i])
            {
                int u=e[i];
                if(cost[u]>cost[x]+bs[i]&&v[i]>0)
                {
                    cost[u]=cost[x]+bs[i];
                    pre[u]=x;qmb[u]=i;
                    flow[u]=min(flow[x],v[i]);
                    if(!vis[u]){q.push(u);vis[u]=1;}
                }
            }
        }
        return pre[ed];
    }
    void ek(int st,int ed)
    {
        while(spfa(st,ed))
        {
            int dq=ed;
            mxflow+=flow[ed];
            mncos+=flow[ed]*cost[ed];
            while(dq!=st)
            {
                int qm=pre[dq],qmw=qmb[dq];
                v[qmw]-=flow[ed];
                v[(qmw&1)?qmw+1:qmw-1]+=flow[ed];
                dq=qm;
            } 
        }
    }
    int main()
    {
        n=read(),m=read();st=read(),ed=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),v=read(),bs=read();
            into(x,y,v,bs);into(y,x,0,-bs);
        }
        ek(st,ed);
        cout<<mxflow<<" "<<mncos; 
        return 0;
    }
    EK_费用流

    exkmp

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=1e5+10;
    int la,lb;
    char a[N],b[N];
    int pre[N],extd[N];//长度 
    void ycl()
    {
        int qm=1;pre[1]=lb;
        while(b[qm]==b[qm+1]&&qm<=lb) qm++;
        pre[2]=qm-1;qm=2;
        for(int i=3;i<=lb;i++)
        {
            int hm=pre[qm]+qm-1,len=pre[i-qm+1];
            if(i+len-1<hm) pre[i]=len;
            else 
            {
                int w=(hm>i)?hm-i+1:0;
                while(i+w<=lb&&b[1+w]==b[i+w]) w++;
                pre[i]=w;qm=i; 
            }
        }
    }
    void exkmp()
    {
        int qm=1;
        while(a[qm]==b[qm]&&qm<=min(la,lb)) qm++;
        extd[1]=qm-1;qm=1;
        for(int i=2;i<=la;i++)
        {
            int hm=extd[qm]+qm-1,len=pre[i-qm+1];
            if(i+len-1<hm) extd[i]=len;
            else
            {
                int w=(hm>i)?hm-i+1:0;
                while(1+w<=lb&&i+w<=la&&b[1+w]==a[i+w]) w++;
                extd[i]=w;qm=i;
            }
        }
    }
    int main()//求出b与(a的每一个后缀)的最长公共前缀
    {
        scanf("%s",a+1);la=strlen(a+1);
        scanf("%s",b+1);lb=strlen(b+1);
        ycl();exkmp();
        for(int i=1;i<=lb;i++) cout<<pre[i]<<" ";cout<<endl;
        for(int i=1;i<=la;i++) cout<<extd[i]<<" ";
    }
    exkmp

    kmp

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=1000010;
    int ans;
    int la,lb;
    char a[N],b[N];
    int pre[N];
    void ycl()
    {
        int qm=0;pre[1]=0;
        for(int i=2;i<=lb;i++)
        {
            while(qm&&(b[i]!=b[qm+1])) qm=pre[qm];
            if(b[i]==b[qm+1]) qm++;
            pre[i]=qm; 
        }
    }
    void kmp()
    {
        int qm=0;
        for(int i=1;i<=la;i++)
        {
            while(qm&&(a[i]!=b[qm+1])) qm=pre[qm];
            if(a[i]==b[qm+1]) qm++;
            if(qm==lb) qm=pre[qm],ans++;
        }
    }
    int main()//b在a中几次 
    {
        scanf("%s",a+1);la=strlen(a+1);
        scanf("%s",b+1);lb=strlen(b+1);
        ycl();kmp();cout<<ans;
        return 0;
    }
    kmp

    马拉车

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define C getchar()-48
    inline ll read()
    {
        ll s=0,r=1;
        char c=C;
        for(;c<0||c>9;c=C) if(c==-3) r=-1;
        for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
        return s*r;
    }
    const int N=11000010;
    int la,ans;
    char a[N<<1];
    int pre[N<<1]; //除中点半径长度 
    void ycl()
    {
        for(int i=la;i>=1;i--) a[i<<1]=a[i],a[(i<<1)-1]='#';la=la*2+1;a[la]='#';
    }
    void mnch()
    {
        int qm=0;
        for(int i=1;i<=la;i++)
        {
            int hm=qm+pre[qm];
            if(i<=hm) pre[i]=min(pre[qm*2-i],hm-i);
            while(1<=i-pre[i]&&i+pre[i]<=la&&a[i-pre[i]]==a[i+pre[i]]) pre[i]++;pre[i]--;
            if(hm<=i+pre[i]) qm=i; 
        }
    }
    int main()
    {
        scanf("%s",a+1);la=strlen(a+1);
        ycl();mnch();
        for(int i=1;i<=la;i++) ans=max(ans,pre[i]);
        cout<<ans; 
        return 0;
    }
    manacher

    ...

  • 相关阅读:
    C++ Programming Language中的narrow_cast实现
    使用反射处理protobuf数据结构
    Qt中三种解析xml的方式
    iterator简单描述
    关于Strategy和State设计模式
    Jedis连接redis客户端
    Redis基础命令
    redis的安装和启动linux环境
    Redis简介和常见的面试题
    SSM框架整合
  • 原文地址:https://www.cnblogs.com/1436177712qqcom/p/10235650.html
Copyright © 2020-2023  润新知