板子
- 有些东西很重要,但又不常用
- 如果考试的时候忘了,又恰巧考了,那不就 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;
}