有错的话欢迎大佬指出 会尽快订正的
自己用的标准开头

#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; }
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); } */
高斯消元

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)); }
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; }
倍增版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; }
多项式求逆

#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;不取 }
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; }
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;
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; }
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]; }
点分治

#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; }
数论分块

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; }
笛卡尔树建树

#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; }
高次求和

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; }
扫描线

#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; }
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; }
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; }
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]<<" "; }
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; }
马拉车

#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; }
...