模板

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

自己用的标准开头

#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

...

原文地址:https://www.cnblogs.com/1436177712qqcom/p/10235650.html