OI模板库
有时间就加一点吧....
Tarjan
缩点
namespace Tarjan{
int col[N],num[N],dfn[N],low[N],cnt,colornum,val[N];
bool ins[N];
stack<int>s;
vector<int>g[N];
vector<int>e[N];
int a[N];
inline void tarjan(int u){
dfn[u]=low[u]=++cnt;
s.push(u);ins[u]=1;
for(auto v:g[u]){
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int t;
colornum++;
do{
t=s.top();s.pop();
col[t]=colornum;
num[colornum]++;
val[colornum]+=a[t];
ins[t]=0;
}while(t!=u);
}
}
}using namespace Tarjan;
求割点
vector<node>e;
vector<int>g[N];
int dfn[N],low[N],cnt;
int cut[N],rt;
inline void dfs(int u,int from){
dfn[u]=low[u]=++cnt;
int son=0;
for(auto i:g[u]){
if((i^from)==1)continue;
int v=e[i].v;
son++;
if(!dfn[v]){
dfs(v,i);
low[u]=min(low[u],low[v]);
if(u==rt&&son>1)cut[u]=1;
else if(u!=rt&&low[v]>=dfn[u])cut[u]=1;
}
else low[u]=min(low[u],dfn[v]);
}
}
求割边
void dfs(int u,int from){
dfn[u]=low[u]=++idx;
for(auto [v,e]:g[u]){
if((e^1)==from)continue;
if(!dfn[v]){
dfs(v,e);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u])cutedg[e>>1]=1;
}
else low[u]=min(low[u],dfn[v]);
}
}
关于tarjan的题目,一定要注意重边,不仅是开始的重边,也有缩点之后的重边。
圆方树
void Tarjan(int u) {
printf(" Enter : #%d\n", u);
low[u] = dfn[u] = ++dfc; // low 初始化为当前节点 dfn
stk[++tp] = u; // 加入栈中
for (int v : G[u]) { // 遍历 u 的相邻节点
if (!dfn[v]) { // 如果未访问过
Tarjan(v); // 递归
low[u] = std::min(low[u], low[v]); // 未访问的和 low 取 min
if (low[v] == dfn[u]) { // 标志着找到一个以 u 为根的点双连通分量
++cnt; // 增加方点个数
printf(" Found a New BCC #%d.\n", cnt - N);
// 将点双中除了 u 的点退栈,并在圆方树中连边
for (int x = 0; x != v; --tp) {
x = stk[tp];
T[cnt].push_back(x);
T[x].push_back(cnt);
printf(" BCC #%d has vertex #%d\n", cnt - N, x);
}
// 注意 u 自身也要连边(但不退栈)
T[cnt].push_back(u);
T[u].push_back(cnt);
printf(" BCC #%d has vertex #%d\n", cnt - N, u);
}
} else
low[u] = std::min(low[u], dfn[v]); // 已访问的和 dfn 取 min
}
printf(" Exit : #%d : low = %d\n", u, low[u]);
printf(" Stack:\n ");
for (int i = 1; i <= tp; ++i) printf("%d, ", stk[i]);
puts("");
}
虚树
void add(int u,int v){
adj[u].push_back(v);
//adj[v].push_back(u);
}
void build(int m){
sort(a.begin(),a.end(),cmp);
a.push_back(1);
up(i,0,m-2){
a.push_back(lca(a[i],a[i+1]));
}
sort(a.begin(),a.end(),cmp);
a.erase(unique(a.begin(),a.end()),a.end());
int len=a.size();
t=len;
for(int i=0;i<len-1;i++){
int lc=(lca(a[i],a[i+1]));
add(lc,a[i+1]);
}
}
cdq
struct node{
int a,b,c,w,ans;
}d[500500],a[500500];
int n,m,len;
int ans[500500];
inline bool cmp(node x,node y){
if(x.a==y.a){
if(x.b==y.b)return x.c<y.c;
return x.b<y.b;
}
return x.a<y.a;
}
int tr[500500];
inline int lowbit(int x){return x&(-x);}
inline int ask(int i){
int ans=0;
for(;i;i-=lowbit(i))ans+=tr[i];
return ans;
}
inline void add(int i,int k){
for(;i<=m;i+=lowbit(i))tr[i]+=k;
}
inline bool cmpy(node u,node v){
if(u.b==v.b)return u.c<v.c;
return u.b<v.b;
}
inline void cdq(int l,int r){
if(l==r)return;
int mid=(l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
sort(a+l,a+mid+1,cmpy);
sort(a+mid+1,a+r+1,cmpy);
int i=mid+1,j=l;
for(;i<=r;i++){
while(a[j].b<=a[i].b&& j<=mid)add(a[j].c,a[j].w),j++;
a[i].ans+=ask(a[i].c);
}
for(i=l;i<j;i++)add(a[i].c,-a[i].w);
}
signed main(){
n=read();m=read();
for(int i=1;i<=n;i++){
d[i].a=read();
d[i].b=read();
d[i].c=read();
}
sort(d+1,d+1+n,cmp);
int c=0;
for(int i=1;i<=n;i++){
c++;
if(d[i].a!=d[i+1].a ||d[i].b!=d[i+1].b ||d[i].c!=d[i+1].c){
a[++len]=d[i];
a[len].w=c;
c=0;
}
}
cdq(1,len);
for(int i=1;i<=len;i++)ans[a[i].ans+a[i].w-1]+=a[i].w;
for(int i=0;i<n;i++)printf("%d\n",ans[i]);
return 0;
}
树链剖分求LCA
struct treelca{
int siz[N],son[N],fa[N],dep[N],top[N];
inline void dfs1(int u,int from){
siz[u]=1;son[u]=0;
dep[u]=dep[from]+1;
for(auto v:g[u]){
if(v==from) continue;
fa[v]=u;dfs1(v,u);
if(siz[v]>siz[son[u]])son[u]=v;
siz[u]+=siz[v];
}
}
inline void dfs2(int u,int tp){
top[u]=tp;
if(son[u]!=0) dfs2(son[u],tp);
for(auto v:g[u]){
if(v==fa[u]||v==son[u]) continue;
dfs2(v,v);
}
}
inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]])x=fa[top[x]];
else y=fa[top[y]];
}
return dep[x]<dep[y]?x:y;
}
}T;
ST表
code
struct ST{
int dp[N][20],pos[N][20];
inline void build(int l,int r,int arr[]){
up(i,l,r)dp[i-l+1][0]=arr[i];
up(i,l,r)pos[i][0]=i;
int res=0;
for(int j=1;(1<<j)<=r-l+1;j++){
for(int i=l;i+(1<<j)-1<=r;i++){
int x=pos[i-l+1][j-1],y=pos[i-l+1+(1<<(j-1))][j-1];
dp[i-l+1][j]=max(dp[i-l+1][j-1],dp[i-l+1+(1<<(j-1))][j-1]);
pos[i-l+1][j]=arr[x]>arr[y]?x:y;
}
}
}
inline int ask(int l,int r){
int k=log2(r-l+1);
return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
inline int askpos(int l,int r,int arr[]){
int k=log2(r-l+1);
int x=pos[l][k],y=pos[r-(1<<k)+1][k];
return arr[x]>arr[y]?x:y;
}
}T;
快读快出
namespace IO{
inline int read(){
char c=getchar();int x=0,fh=0;
while(c<'0'||c>'9'){fh|=c=='-';c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return fh?-x:x;
}
inline void wt(int x){
if(x<0){x=-x;putchar('-');}
if(x>9)wt(x/10);
putchar((x%10)^48);
}
inline void write(int x,bool op){
wt(x);
putchar(op?'\n':' ');
}
}using namespace IO;
AC自动机
struct AC_auto{
int tr[N][26],cnt,ed[N],fail[N];
inline void insert(char s[]){
int len=strlen(s+1),p=0;
up(i,1,len){
int ch=s[i]-'a';
if(!tr[p][ch])tr[p][ch]=++cnt;
p=tr[p][ch];
}
ed[p]++;
}
queue<int>q;
inline void getfail(){
up(i,0,25)if(tr[0][i])q.push(tr[0][i]);
while(q.size()){
int u=q.front();q.pop();
up(i,0,25){
int v=tr[u][i];
if(v){
fail[v]=tr[fail[u]][i];
q.push(v);
}
else tr[u][i]=tr[fail[u]][i];
}
}
}
inline int ask(char s[]){
int len=strlen(s+1),p=0,ans=0;
up(i,1,len){
int ch=s[i]-'a';
p=tr[p][ch];
for(int v=p;v&&ed[v]!=-1;v=fail[v])ans+=ed[v],ed[v]=-1;
}
return ans;
}
}T;
Dinic
struct Dinic{
struct edge{
int u,v,cap,flow;
};
vector<edge>edges;
vector<int>g[N];
int cur[N],d[N];
bool vis[N];
inline void add(int u,int v,int cap){
edges.push_back({u,v,cap,0});
edges.push_back({v,u,0,0});
int t=edges.size();
g[u].push_back(t-2);
g[v].push_back(t-1);
}
inline bool bfs(int s,int t){
memset(vis,0,sizeof vis);
queue<int>q;
q.push(s);
d[s]=0;vis[s]=1;
while(q.size()){
int u=q.front();q.pop();
for(auto i:g[u]){
auto e=edges[i];
if(!vis[e.v]&&e.cap>e.flow){
vis[e.v]=1;
d[e.v]=d[u]+1;
q.push(e.v);
}
}
}
return vis[t];
}
inline int dfs(int u,int a,int t){
if(u==t||a==0)return a;
int flow=0,f;
for(int &i=cur[u];i<g[u].size();i++){
auto& e=edges[g[u][i]];
if(d[u]+1==d[e.v]&&(f=dfs(e.v,min(a,e.cap-e.flow),t))>0){
e.flow+=f;
edges[g[u][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
inline int maxflow(int s,int t){
int flow=0;
while(bfs(s,t)){
memset(cur,0,sizeof cur);
flow+=dfs(s,inf,t);
}
return flow;
}
}E;
struct Dinic{
struct edge{
int u,v,cap,flow,w;
};
vector<edge>edges;
vector<int>g[N];
inline void add(int u,int v,int cap,int w){
edges.push_back({u,v,cap,0,w});
edges.push_back({v,u,0,0,-w});
int t=edges.size();
g[u].push_back(t-2);
g[v].push_back(t-1);
}
bool vis[N];
int dis[N],cur[N];
queue<int>q;
inline bool spfa(int s,int t){
memset(dis,0x3f,sizeof dis);
memset(vis,0,sizeof vis);
dis[s]=0;vis[s]=1;
q.push(s);
while(q.size()){
int u=q.front();q.pop();
vis[u]=0;
for(auto i:g[u]){
auto [_,v,cap,flow,w]=edges[i];
if(dis[v]>dis[u]+w&&cap>flow){
dis[v]=dis[u]+w;
if(!vis[v]){
vis[v]=1;
q.push(v);
if(dis[q.front()]>dis[q.back()])swap(q.front(),q.back());
}
}
}
}
return dis[t]<inf;
}
inline int dfs(int u,int a,int t){
if(u==t||a==0)return a;
vis[u]=1;
int flow=0;
for(int &i=cur[u];i<g[u].size();i++){
auto &e=edges[g[u][i]];
if(!vis[e.v]&&dis[e.v]==dis[u]+e.w&&e.cap>e.flow){
int res=dfs(e.v,min(a,e.cap-e.flow),t);
flow+=res;
e.flow+=res;
edges[g[u][i]^1].flow-=res;
a-=res;
if(a==0)break;
}
}
vis[u]=0;
return flow;
}
inline pii mincostmaxflow(int s,int t){
int res,flow=0,cost=0;
while (spfa(s,t)) {
memset(cur, 0, sizeof(cur));
while ((res=dfs(s,inf,t)))flow += res,cost += res * dis[t];
}
return {flow,cost};
}
}E;
lucas
inline int ksm(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int inv[N],fac[N];
inline void init(){
inv[0]=fac[0]=1;
up(i,1,mod+10){
fac[i]=fac[i-1]*i%mod;
inv[i]=ksm(fac[i],mod-2);
}
}
inline int C(int n,int m){
if(n<m) return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
inline int lucas(int n,int m){
if(m==0) return 1;
return (C(n%mod,m%mod)*lucas(n/mod,m/mod))%mod;
}
Z函数
int n,m;
char a[N],b[N];
int z[N],p[N];
signed main() {
scanf("%s",a+1);
scanf("%s",b+1);
int lenb=strlen(b+1);
z[1]=lenb;
for(int i=2,l=0,r=0;i<=lenb;i++) {
z[i]=i>r?0:min(z[i-l+1],r-i+1);
while(b[1+z[i]]==b[i+z[i]])z[i]++;
if(i+z[i]-1>r)l=i,r=i+z[i]-1;
}
int lena=strlen(a+1);
for(int i=1,l=0,r=0;i<=lena;i++){
p[i]=i>r?0:min(z[i-l+1],r-i+1);
while(p[i]<lenb&&b[1+p[i]]==a[i+p[i]])p[i]++;
if(i+p[i]-1>r)l=i,r=i+p[i]-1;
}
int ans=0;
up(i,1,lenb)ans^=i*(z[i]+1);
cout<<ans<<endl;
ans=0;
up(i,1,lena)ans^=i*(p[i]+1);
cout<<ans<<endl;
return 0;
}
失配树
inline void failtree(){
dn(i,n,1){
siz[i]++;
if(nxt[i])siz[nxt[i]]+=siz[i];
if(siz[i]>=siz[son[nxt[i]]])son[nxt[i]]=i;
}
up(i,1,n){
dep[i]=dep[nxt[i]]+1;
if(son[nxt[i]]!= i)top[i] = i;
else top[i]=top[nxt[i]];
fa[i]=nxt[i];
}
}
bool vis[N];
signed main(){
scanf("%s",s+1);
n=strlen(s+1);
getnxt();
T.failtree();
int q=read();
int l,r;
while(q--){
l=nxt[read()];r=nxt[read()];
write(T.lca(l,r),1);
}
return 0;
}
高斯消元
namespace gauss{
ldb a[500][500];
int n;
inline void work(){
for(int r=1,c=1;c<=n;c++,r++){
int t=r;
up(i,r+1,n){
if(fabs(a[i][c])>fabs(a[t][c]))t=i;
}
up(i,c,n+1)swap(a[t][i],a[r][i]);
if(!a[c][c]){
puts("No Solution");
exit(0);
}
dn(i,n+1,c)a[r][i]/=a[r][c];
up(i,r+1,n){
dn(j,n+1,c){
a[i][j]-=a[i][c]*a[r][j];
}
}
}
dn(i,n,2){
dn(j,i-1,1){
a[j][n+1]-=a[i][n+1]*a[j][i];
a[j][i]=0;
}
}
}
inline void print(){
up(i,1,n){
printf("%.3Lf ",a[i][n+1]);
}
}
}using namespace gauss;
线性基
namespace Linear_basis{
int p[100],cnt,flag0=0;
inline void insert(int x){
if(x==0)flag0=1;
dn(i,62,0){
if(x&(1ll<<i)){
if(!p[i]){
p[i]=x;
cnt++;
return;
}
else x^=p[i];
}
}
}
inline bool ask(int x){
dn(i,62,0){
if(x&(1ll<<i)){
x^=p[i];
}
}
return x==0;
}
inline int askmax(int x) {
int ans=x;
dn(i,62,0)if((ans^p[i])>ans)ans^=p[i];
return ans;
}
inline int askmin(int x){
int ans=x;
dn(i,62,0)if(ans>(p[i]^ans))ans^=p[i];
return ans;
}
}using namespace Linear_basis;
点分治
int n,m;
vector<pii>g[N];
int lim;
bool del[N];
inline int getsiz(int u,int from){
if(del[u])return 0;
int res=1;
for(auto [v,w]:g[u]){
if(v==from)continue;
res+=getsiz(v,u);
}
return res;
}
inline int getwc(int u,int from,int tot,int&wc){
if(del[u])return 0;
int sum=1,maxl=0;
for(auto [v,w]:g[u]){
if(v==from)continue;
int t=getwc(v,u,tot,wc);
maxl=max(maxl,t);
sum+=t;
}
maxl=max(maxl,tot-sum);
if(maxl<=tot/2)wc=u;
return sum;
}
inline void dfs(int u,int from,int dis,vector<int>&q){
if(del[u])return;
q.push_back(dis);
for(auto [v,w]:g[u]){
if(v==from)continue;
dfs(v,u,dis+w,q);
}
}
inline int get(vector<int>&a){
sort(a.begin(),a.end());
int res=0,len=a.size();
for(int i=len-1,j=-1;i>=0;i--){
while(j+1<i&&a[j+1]+a[i]<=lim)j++;
j=min(j,i-1);
res+=j+1;
}
return res;
}
inline int clac(int u){
if(del[u])return 0;
int res=0;
getwc(u,0,getsiz(u,0),u);
del[u]=1;
vector<int>p;
for(auto [v,w]:g[u]){
if(del[v])continue;
vector<int>q;
dfs(v,u,w,q);
res-=get(q);
for(auto x:q){
p.push_back(x);
if(x<=lim)res++;
}
}
res+=get(p);
for(auto [v,w]:g[u])res+=clac(v);
return res;
}
李超线段树
int n,last;
struct line{
ldb k,b;
}p[N];
int cnt;
inline void add(int x0, int y0, int x1, int y1) {
cnt++;
if(x0==x1)p[cnt].k=0,p[cnt].b=max(y0, y1);
else p[cnt].k=1.0*(y1-y0)/(x1-x0),p[cnt].b=y0-p[cnt].k*x0;
}
int s[N];
inline ldb calc(int id,int d) { return p[id].b+p[id].k*d;}
inline int cmp(ldb x,ldb y) {
if(x-y>eps)return 1;
if(y-x>eps)return -1;
return 0;
}
inline void change(int k,int l,int r,int u){
int &v=s[k],mid=(l+r)>>1;
int bmid=cmp(calc(u,mid),calc(v,mid));
if(bmid==1||(!bmid&&u<v))swap(u,v);
int bl=cmp(calc(u,l),calc(v,l)),br=cmp(calc(u,r),calc(v,r));
if(bl==1||(!bl&&u<v))change(lc,l,mid,u);
if(br==1||(!br&&u<v))change(rc,mid+1,r,u);
}
inline void insert(int k,int tl,int tr,int l,int r,int u){
if(l<=tl&&tr<=r) {
change(k,tl,tr,u);
return;
}
int mid=(tl+tr)>>1;
if(l<=mid)insert(lc,tl,mid,l,r,u);
if(mid<r)insert(rc,mid+1,tr,l,r,u);
}
inline pdi pmax(pdi x,pdi y){
if(cmp(x.fi,y.fi)==-1)return y;
else if(cmp(x.fi,y.fi)==1)return x;
return x.se<y.se?x:y;
}
inline pdi ask(int k,int l,int r,int d){
if (r<d||d<l)return {0,0};
int mid=(l+r)>>1;
db res=calc(s[k],d);
if(l==r)return{res,s[k]};
return pmax({res,s[k]},pmax(ask(lc,l,mid,d),ask(rc,mid+1,r,d)));
}
signed main(){
n=read();
int op,k,x0,y0,x1,y1;
up(i,1,n){
op=read();
if(op==1){
x0=(read()+last-1+mod1)%mod1+1;
y0=(read()+last-1+mod2)%mod2+1;
x1=(read()+last-1+mod1)%mod1+1;
y1=(read()+last-1+mod2)%mod2+1;
if (x0>x1)swap(x0,x1),swap(y0,y1);
add(x0,y0,x1,y1);
insert(1,1,mod1,x0,x1,cnt);
}
else {
k=read();
k=(k+last-1+mod1)%mod1+1;
last=ask(1,1,mod1,k).second;
cout<<(last)<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号