板子

板子

  • 有些东西很重要,但又不常用
  • 如果考试的时候忘了,又恰巧考了,那不就 GG 了
  • 所以我就把这类东西记到这里

离散化

/*************************************************************************
    > File Name: lsh.cpp
    > Author: Typedef 
    > Mail: 1815979752@qq.com 
    > Created Time: 2021-08-05 11:08:46
    > blog: https://www.cnblogs.com/Illyasviel
 ************************************************************************/
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,m;
int a[N],b[N],c[N];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
    sort(b+1,b+n+1);
    int m=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++) c[i]=lower_bound(b+1,b+m+1,a[i])-b;
    for(int i=1;i<=n;i++) printf("%d ",c[i]);
    puts("");
    return 0;
}

快读

template<class T>void qread(T &x){
    x=0;bool f=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    if(f) x=-x;
}

矩阵

struct Matrix{
    int n;
    int a[N][N];
    Matrix(int _n){n=_n;memset(a,0,sizeof(n));}
    void init(){
        for(int i=0;i<n;i++) a[i][i]=1;
    }
    friend Matrix operator*(const Matrix &x,const Matrix &y){
        Matrix res(x.n);
        for(int k=0;k<x.n;k++)
            for(int i=0;i<x.n;i++)
                for(int j=0;j<x.n;j++)
                    res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
        return res;
    }
};
Matrix qpow(Matrix a,ll b){
    Matrix res(a.n);
    res.init();
    while(b){
        if(b&1) res=res*a;
        a=a*a;
        b>>=1ll;
    }
    return res;
}

高精

struct HP{
	int p[M],len;
	HP(){
		memset(p,0,sizeof(p));
		len=0;
	}
	void print(){
		printf("%d",p[len]);
		for(int i=len-1;i>0;i--){
			if(!p[i]){
				printf("0000");
				continue;
			}
			for(int k=10;k*p[i]<mod;k*=10)
				printf("0");
			printf("%d",p[i]);
		}
	}
};
HP operator + (const HP &a,const HP &b){
	HP c;
	c.len=max(a.len,b.len);
	int x=0;
	for(int i=1;i<=c.len;i++){
		c.p[i]=a.p[i]+b.p[i]+x;
		x=c.p[i]/mod;
		c.p[i]%=mod;
	}
	if(x) c.p[++c.len]=x;
	return c;
}
HP operator * (const HP &a,const int &b){
	HP c;
	c.len=a.len;
	int x=0;
	for(int i=1;i<=c.len;i++){
		c.p[i]=a.p[i]*b+x;
		x=c.p[i]/mod;
		c.p[i]%=mod;
	}
	while(x) c.p[++c.len]=x%mod,x/=mod;
	return c;
}
HP max(const HP &a,const HP &b){
	if(a.len>b.len) return a;
	else if(a.len<b.len) return b;
	for(int i=a.len;i>0;i--)
		if(a.p[i]>b.p[i]) return a;
		else if(a.p[i]<b.p[i]) return b;
	return a;
}

\(\mu\)

void init(int n){
    mu[1]=1;
    int cnt=0;
    for(int i=2;i<n;i++){
        if(!st[i]) prime[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&i*prime[j]<n;j++){
            st[i*prime[j]]=1;
            mu[i*prime[j]]=-mu[i];
            if(!(i%prime[j])){
                mu[i*prime[j]]=0;
                break;
            }
        }
    }
}

\(\varphi\)

void init(int n){
    int cnt=0;
    for(int i=2;i<n;i++){
        if(!st[i]) prime[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*prime[j]<n;j++){
            st[i*prime[j]]=1;
            phi[i*prime[j]]=phi[i]*(prime[j]-1);
            if(!(i%prime[j])){
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
        }
    }
}

\(\sigma_1\)

void init(int n){
    sig[1]=1;
    int cnt=0;
    for(int i=2;i<n;i++){
        if(!st[i]) prime[++cnt]=i,sig[i]=i+1;
        for(int j=1;j<=cnt&&i*prime[j]<n;j++){
            st[i*prime[j]]=1;
            sig[i*prime[j]]=sig[i]*(prime[j]+1);
            if(!(i%prime[j])){
                sig[i*prime[j]]=(sig[i]-sig[i/prime[j]])*prime[j]+sig[i];
                break;
            }
        }
    }
}

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

#include<bits/stdc++.h>
using namespace std;
const int N=200010,M=20010;
int n,m;
int a[N];
vector<int> nums;
struct node{
	int l,r;
	int cnt;
}tr[N*4+N*17];
int root[N],idx;
int find(int x){
	//返回原数的离散值
	return lower_bound(nums.begin(),nums.end(),x)-nums.begin();
}
int build(int l,int r){
	//线段树新建节点
	int p=++idx;
	if(l==r) return p;
	int mid=l+r>>1;
	tr[p].l=build(l,mid),tr[p].r=build(mid+1,r);
	return p;
}
int insert(int p,int l,int r,int x){//p是历史版本的线段树,l是区间左端点,r是区间右端点,x是要加入的数
	//新建一颗线段树
	int q=++idx;
	tr[q]=tr[p];//复制
	if(l==r){
		tr[q].cnt++;
		return q;
	}
	int mid=l+r>>1;
	//判断哪个子节点发生了变化
	if(x<=mid) tr[q].l=insert(tr[p].l,l,mid,x);
	else tr[q].r=insert(tr[p].r,mid+1,r,x);
	//update
	tr[q].cnt=tr[tr[q].l].cnt+tr[tr[q].r].cnt;
	return q;
}
int query(int q,int p,int l,int r,int k){
	//
	if(l==r) return r;
	int cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;
	int mid=l+r>>1;
	if(k<=cnt) return query(tr[q].l,tr[p].l,l,mid,k);
	else return query(tr[q].r,tr[p].r,mid+1,r,k-cnt);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		nums.push_back(a[i]);
	}
	sort(nums.begin(),nums.end());
	nums.erase(unique(nums.begin(),nums.end()),nums.end());
	root[0]=build(0,nums.size()-1);
	for(int i=1;i<=n;i++) root[i]=insert(root[i-1],0,nums.size()-1,find(a[i]));
	while(m--){
		int l,r,k;
		scanf("%d%d%d",&l,&r,&k);
		printf("%d\n",nums[query(root[r],root[l-1],0,nums.size()-1,k)]);
	}
	system("pause");
	return 0;
}

普通平衡树( \(\rm{fhq}\) 做法)

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+7;
int T,cnt;
int n,m,root;
int x,y,z;
template<class T>void qread(T &x){
    x=0;bool f=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    if(f) x=-x;
}
struct Node{
    int sz;
    int s[2];
    int fix,val;
}tr[N];
void pushup(int p){
    tr[p].sz=tr[tr[p].s[0]].sz+tr[tr[p].s[1]].sz+1;
}
int insert(int p){
    tr[++cnt].sz=1;
    tr[cnt].val=p;
    tr[cnt].fix=rand();
    return cnt;
}
int merge(int p,int q){
    if(!p||!q) return  p^q;
    if(tr[p].fix<tr[q].fix){
        tr[p].s[1]=merge(tr[p].s[1],q);
        pushup(p);
        return p;
    }
    else{
        tr[q].s[0]=merge(p,tr[q].s[0]);
        pushup(q);
        return q;
    } 
}
void split(int u,int k,int &x,int &y){
    if(!u) x=y=0;
    else{
        if(tr[u].val<=k)
            x=u,split(tr[u].s[1],k,tr[u].s[1],y);
        else y=u,split(tr[u].s[0],k,x,tr[u].s[0]);
        pushup(u);
    }
    return;
}
int getkth(int u,int k){
    while(true){
        if(k<=tr[tr[u].s[0]].sz) u=tr[u].s[0];
        else if(k==tr[tr[u].s[0]].sz+1) return u;
        else k-=tr[tr[u].s[0]].sz+1,u=tr[u].s[1];
    }
}
int main(){
    qread(T);
    srand(time(0));
    while(T--){
        int op,a;
        qread(op),qread(a);
        if(op==1){
            split(root,a,x,y);
            root=merge(merge(x,insert(a)),y);
        }
        else if(op==2){
            split(root,a,x,z);
            split(x,a-1,x,y);
            y=merge(tr[y].s[0],tr[y].s[1]);
            root=merge(merge(x,y),z);
        }
        else if(op==3){
            split(root,a-1,x,y);
            printf("%d\n",tr[x].sz+1);
            root=merge(x,y);
        }
        else if(op==4)
            printf("%d\n",tr[getkth(root,a)].val);
        else if(op==5){
            split(root,a-1,x,y);
            printf("%d\n",tr[getkth(x,tr[x].sz)].val);
            root=merge(x,y);
        }
        else{
            split(root,a,x,y);
            printf("%d\n",tr[getkth(y,1)].val);
            root=merge(x,y);
        }
    }
    return 0;
}

tarjan

void tarjan(int u){
	dfn[u]=low[u]=++timestamp;
	stk[++top]=u,in_stk[u]=true;
	for(int i=h[u];~i;i=ne[i]){
		int v=e[i];
		if(!dfn[v]){
			tarjan(v);
			low[u]=min(low[u],low[v]);
		}
		else if(in_stk[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u]){
		++scc_cnt;
		int v;
		do{
			v=stk[top--];
			in_stk[v]=false;
			id[v]=scc_cnt;
		}while(v!=u);
	}
	return;
}
posted @ 2021-09-17 21:12  actypedef  阅读(93)  评论(0编辑  收藏  举报