模版

LaTeX

考场

编译命令:

g++ fhq.cpp -o fhq -O2 -std=c++14 -Wall -lm -fsanitize=address,undefined
快读快写
il int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
il void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
对拍

//windows
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
int main(){
    int miku=0;
    while(1){
        cout<<++miku<<'\n';
        system("data.exe > in");
        system("std.exe < in > std");
        system("ans.exe < in > mine");
        if(system("fc mine std"))return 0;
        Sleep(200);
    }
}


//linux
#include <bits/stdc++.h>
using namespace std;
int main(){
    system("g++ data.cpp -o data");
    system("g++ a.cpp -o a -O2 -std=c++14");
    system("g++ b.cpp -o b -O2 -std=c++14");
    int cnt=0;
    while(1){
        cout<<++cnt<<": ";
        system("./data > in");
        system("./a < in > out");
        system("./b < in > ans");
        if(system("diff out ans -B -w")){cout<<"WA"<<'\n';}
        else cout<<"AC"<<'\n';
    }
}

数据结构

树状数组
#include <bits/stdc++.h>
using namespace std;
int a[500001],tree[500001];
#define lowbit(x) (x&(-x))
int n,m;
void update(int x,int key){//单点修改 
	while(x<=n){
		tree[x]+=key;
		x+=lowbit(x);
	}
}
int query(int x){//区间查询 
	int sum=0;
	while(x>0){
		sum+=tree[x];
		x-=lowbit(x);
	}
	return sum;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		update(i,a[i]-a[i-1]);//将差分数组初始化
	}
	for(int i=1;i<=m;i++){
		int doo,x,y,k;
		cin>>doo;
		if(doo==1){//修改[x,y]操作 
			cin>>x>>y>>k;
			update(x,k);
			update(y+1,-k);
		} 
		else if(doo==2){//查询队列和操作;
			cin>>x;
			cout<<query(x)<<endl; 
		}
	} 
	return 0;
}
 
//=============================================
#include <bits/stdc++.h>
using namespace std;
int a[500001],tree[500001];
#define lowbit(x) (x&(-x))
int n,m;
void update(int x,int key){//单点修改 
	while(x<=n){
		tree[x]+=key;
		x+=lowbit(x);
	}
}
int query(int x){//单点查询 
	int sum=0;
	while(x>0){
		sum+=tree[x];
		x-=lowbit(x);
	}
	return sum;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		update(i,a[i]);//将树状数组初始化	
	}
	for(int i=1;i<=m;i++){
		int doo,x,y;
		cin>>doo>>x>>y;
		if(doo==1){//修改x值操作 
			update(x,y); 
		} 
		else if(doo==2){//查询队列和操作;
			cout<<(query(y)-query(x-1))<<endl; 
		}
	} 
	return 0;
} 
FHQ-Treap
#define M 100050
int rt(0),cnt(0);
namespace Treap{
    struct node{
        int l,r;
        int key,pri;
        int siz;
    }t[M];
    mt19937 gen(0);
    il void add_point(int x){
        ++cnt;
        t[cnt].l=t[cnt].r=0;
        t[cnt].siz=1;
        t[cnt].key=x;
        t[cnt].pri=gen();
    }
    il void push_up(int k){
        t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
    }
    void split(int k,int x,int &L,int &R){
        if(k==0){L=R=0;return;}
        if(x<t[k].key){
            R=k;
            split(t[k].l,x,L,t[k].l);
        }
        else{
            L=k;
            split(t[k].r,x,t[k].r,R);
        }
        push_up(k);
    }
    int merge(int L,int R){
        if(L==0||R==0)return L+R;
        if(t[L].pri>t[R].pri){
            t[L].r=merge(t[L].r,R);
            push_up(L);
            return L;
        }
        else{
            t[R].l=merge(L,t[R].l);
            push_up(R);
            return R;
        }
    }
    void insert(int x){
        int L,R;
        split(rt,x,L,R);
        add_point(x);
        int L1=merge(L,cnt);
        rt=merge(L1,R);
    }
    void del(int x){
        int L,R,p;
        split(rt,x,L,R);
        split(L,x-1,L,p);
        p=merge(t[p].l,t[p].r);
        rt=merge(merge(L,p),R);  
    }   
    int query_rank(int x){
        int L,R; 
        split(rt,x-1,L,R);
        int ans=t[L].siz+1;
        rt=merge(L,R);
        return ans;
    }
    int query_kth(int k,int x){
        if(x==t[t[k].l].siz+1)return k;
        else if(x<t[t[k].l].siz+1)return query_kth(t[k].l,x);
        else return query_kth(t[k].r,x-t[t[k].l].siz-1); 
    }
    int query_pre(int x){
        int L,R;
        split(rt,x-1,L,R);
        int ans=t[query_kth(L,t[L].siz)].key;
        rt=merge(L,R);
        return ans;
    }
    int query_back(int x){
        int L,R;
        split(rt,x,L,R);
        int ans=t[query_kth(R,1)].key;
        rt=merge(L,R);
        return ans;
    }
}
signed main(){
    // freopen("in","r",stdin);
    // freopen("out","w",stdout);
    int n=read();
    for(int i=1;i<=n;i++){
        int opt=read();
        int x=read();
        // cout<<opt<<endl;
        if(opt==1) Treap::insert(x);
        else if(opt==2) Treap::del(x);
        else if(opt==3) Write(Treap::query_rank(x));
        else if(opt==4) Write(Treap::t[Treap::query_kth(rt,x)].key);
        else if(opt==5) Write(Treap::query_pre(x));
        else if(opt==6) Write(Treap::query_back(x));
    }
}
二逼平衡树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define endl '\n'
#define M 100050
#define N 2000050
const int Nan=2147483647;
const int maxn=100000001;
namespace Testify{
    il int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*f;
    }
    il void write(ll x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    il void Write(ll x){write(x);puts("");}
    il void writE(ll x){write(x);putchar(' ');}
}
using namespace Testify;
int root[N];
namespace Treap{
    struct node{
        int l,r;
        int key,pri;
        int siz;
    }t[N];
    int cnt(0);
    mt19937 gen(0);
    il void add_point(int x){
        ++cnt;
        t[cnt].l=t[cnt].r=0;
        t[cnt].key=x;
        t[cnt].pri=gen();
        t[cnt].siz=1;
    }
    il void push_up(int k){
        t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
    }
    void split(int k,int x,int &L,int &R){
        if(k==0){L=R=0;return;}
        if(x<t[k].key){
            R=k;
            split(t[k].l,x,L,t[k].l);
        }
        else{
            L=k;
            split(t[k].r,x,t[k].r,R);
        }
        push_up(k);
    }
    int merge(int L,int R){
        if(L==0||R==0)return L+R;
        if(t[L].pri>t[R].pri){
            t[L].r=merge(t[L].r,R);
            push_up(L);
            return L;
        }
        else{
            t[R].l=merge(L,t[R].l);
            push_up(R);
            return R;
        }
    }
    il void insert(int k,int x){
        int L,R;
        split(root[k],x,L,R);
        add_point(x);
        root[k]=merge(merge(L,cnt),R);
    }
    il void del(int k,int x){
        int L,R,p;
        split(root[k],x,L,R);
        split(L,x-1,L,p);
        p=merge(t[p].l,t[p].r);
        root[k]=merge(merge(L,p),R);
    }
    il int query_rank(int k,int x){
        int L,R;
        split(root[k],x-1,L,R);
        int ans=t[L].siz;
        root[k]=merge(L,R);
        return ans;
    }
    int query_kth(int k,int x){
        if(x==t[t[k].l].siz+1)return k;
        else if(x<t[t[k].l].siz+1)return query_kth(t[k].l,x);
        else return query_kth(t[k].r,x-t[t[k].l].siz-1);
    }
    int query_pre(int k,int x){
        if(k==0)return -Nan;
        if(x<=t[k].key)return query_pre(t[k].l,x);
        int tmp=query_pre(t[k].r,x);
        if(tmp==-Nan)return t[k].key;
        else return tmp;
    }
    int query_back(int k,int x){
        if(k==0)return Nan;
        if(x>=t[k].key)return query_back(t[k].r,x);
        int tmp=query_back(t[k].l,x);
        if(tmp==Nan)return t[k].key;
        else return tmp;
    }
}
int a[M];
namespace Segment_Tree{
    void build(int k,int l,int r){
        for(int i=l;i<=r;i++)Treap::insert(k,a[i]);
        if(l==r)return;
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
    }
    void update(int k,int l,int r,int pos,int val){
        Treap::del(k,a[pos]);
        Treap::insert(k,val);
        if(l==r)return;
        int mid=(l+r)>>1;
        if(pos<=mid)update(k<<1,l,mid,pos,val);
        else update(k<<1|1,mid+1,r,pos,val);
    }
    int query_rk(int k,int l,int r,int L,int R,int x){
        if(L<=l&&r<=R)return Treap::query_rank(k,x);
        int mid=(l+r)>>1;
        int ans=0;
        if(L<=mid)ans+=query_rk(k<<1,l,mid,L,R,x);
        if(R>mid)ans+=query_rk(k<<1|1,mid+1,r,L,R,x);
        return ans;
    }
    int query_pre(int k,int l,int r,int L,int R,int x){
        if(L<=l&&r<=R)return Treap::query_pre(root[k],x);
        int mid=(l+r)>>1;
        int ans=-Nan;
        if(L<=mid)ans=max(ans,query_pre(k<<1,l,mid,L,R,x));
        if(R>mid)ans=max(ans,query_pre(k<<1|1,mid+1,r,L,R,x));
        return ans;
    }
    int query_back(int k,int l,int r,int L,int R,int x){
        if(L<=l&&r<=R)return Treap::query_back(root[k],x);
        int mid=(l+r)>>1;
        int ans=Nan;
        if(L<=mid)ans=min(ans,query_back(k<<1,l,mid,L,R,x));
        if(R>mid)ans=min(ans,query_back(k<<1|1,mid+1,r,L,R,x));
        return ans;
    }
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    Segment_Tree::build(1,1,n);
    while(m--){
        int opt=read();
        if(opt==1){
            int l=read(),r=read(),k=read();
            cout<<Segment_Tree::query_rk(1,1,n,l,r,k)+1<<endl;
        }else if(opt==2){
            int l=read(),r=read(),k=read();
            int L=0,R=maxn,mid,ans;
            while(L<=R){
                mid=(L+R)>>1;
                if(Segment_Tree::query_rk(1,1,n,l,r,mid)+1<=k){L=mid+1;ans=mid;}
                else R=mid-1;
            }
            cout<<ans<<endl;
        }else if(opt==3){
            int pos=read(),k=read();
            Segment_Tree::update(1,1,n,pos,k);
            a[pos]=k;
        }else if(opt==4){
            int l=read(),r=read(),k=read();
            cout<<Segment_Tree::query_pre(1,1,n,l,r,k)<<endl;
        }else if(opt==5){
            int l=read(),r=read(),k=read();
            cout<<Segment_Tree::query_back(1,1,n,l,r,k)<<endl;
        }
    }
}
文艺平衡树
int rt(0);
namespace Treap{
    struct node{
        int l,r;
        int key,pri;
        int siz,tag;
    }t[M];
    mt19937 gen(0);
    int cnt(0);
    il void add_point(int x){
        ++cnt;
        t[cnt].key=x;
        t[cnt].l=t[cnt].r=0;
        t[cnt].siz=1;
        t[cnt].pri=gen();
    }
    il void push_up(int k){
        t[k].siz=t[t[k].l].siz+t[t[k].r].siz+1;
    }
    il void push_down(int k){
        if(!t[k].tag)return;
        swap(t[k].l,t[k].r);
        t[t[k].l].tag^=1;
        t[t[k].r].tag^=1;
        t[k].tag=0;
    }
    void split(int k,int x,int &L,int &R){
        if(k==0){L=R=0;return;}
        push_down(k);
        if(x<t[t[k].l].siz+1){
            R=k;
            split(t[k].l,x,L,t[k].l);
        }
        else{
            L=k;
            split(t[k].r,x-t[t[k].l].siz-1,t[k].r,R);
        }
        push_up(k);
    }
    int merge(int L,int R){
        if(L==0||R==0)return L+R;
        if(t[L].pri>t[R].pri){
            push_down(L);
            t[L].r=merge(t[L].r,R);
            push_up(L);
            return L;
        }
        else{
            push_down(R);
            t[R].l=merge(L,t[R].l);
            push_up(R);
            return R;
        }
    }
    void swp(int x,int y){
        int L,R,p;
        split(rt,y,L,R);
        split(L,x-1,L,p);
        t[p].tag^=1;
        rt=merge(merge(L,p),R);
    }
    void output(int k){
        if(k==0)return;
        push_down(k);
        output(t[k].l);
        writE(t[k].key);
        output(t[k].r);
    }
}
signed main(){
	int n=read(),m=read();
    for(int i=1;i<=n;i++){
        Treap::add_point(i);
        rt=Treap::merge(rt,Treap::cnt);
    }
    while(m--){
        int L=read(),R=read();
        Treap::swp(L,R);
    }
    Treap::output(rt);
    return 0;
} 
吉司机线段树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
const int M=500010;
il int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
il void write(ll x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int a[M];
namespace Segment_Tree{
    struct node{
        ll sum;
        int mxa,mxb,smx,cnt;
        int tag1,tag2,tag3,tag4;
    }t[M<<2];
    il void push_up(int k){
        t[k].sum=t[k<<1].sum+t[k<<1|1].sum;
        t[k].mxa=max(t[k<<1].mxa,t[k<<1|1].mxa);
        t[k].mxb=max(t[k<<1].mxb,t[k<<1|1].mxb);
        if(t[k<<1].mxa==t[k<<1|1].mxa){
            t[k].smx=max(t[k<<1].smx,t[k<<1|1].smx);
            t[k].cnt=t[k<<1].cnt+t[k<<1|1].cnt;
        }else if(t[k<<1].mxa>t[k<<1|1].mxa){
            t[k].smx=max(t[k<<1].smx,t[k<<1|1].mxa);
            t[k].cnt=t[k<<1].cnt;
        }else{
            t[k].smx=max(t[k<<1|1].smx,t[k<<1].mxa);
            t[k].cnt=t[k<<1|1].cnt;
        }
    }
    il void add_tag(int k,int l,int r,int t1,int t2,int t3,int t4){
        t[k].sum+=1ll*t1*t[k].cnt+1ll*t2*(r-l+1-t[k].cnt);
        t[k].mxb=max(t[k].mxb,t[k].mxa+t3);
        t[k].mxa+=t1;
        if(t[k].smx!=INT_MIN)t[k].smx+=t2;
        t[k].tag3=max(t[k].tag3,t[k].tag1+t3);
        t[k].tag4=max(t[k].tag4,t[k].tag2+t4);
        t[k].tag1+=t1;
        t[k].tag2+=t2;
    }
    il void push_down(int k,int l,int r){
        int maxn=max(t[k<<1].mxa,t[k<<1|1].mxa);
        int mid=(l+r)>>1;
        if(t[k<<1].mxa==maxn)add_tag(k<<1,l,mid,t[k].tag1,t[k].tag2,t[k].tag3,t[k].tag4);
        else add_tag(k<<1,l,mid,t[k].tag2,t[k].tag2,t[k].tag4,t[k].tag4);
        if(t[k<<1|1].mxa==maxn)add_tag(k<<1|1,mid+1,r,t[k].tag1,t[k].tag2,t[k].tag3,t[k].tag4);
        else add_tag(k<<1|1,mid+1,r,t[k].tag2,t[k].tag2,t[k].tag4,t[k].tag4);
        t[k].tag1=t[k].tag2=t[k].tag3=t[k].tag4=0;
    }
    void build(int k,int l,int r){
        if(l==r){
            t[k].sum=t[k].mxa=t[k].mxb=a[l];
            t[k].smx=INT_MIN;
            t[k].cnt=1;
            return;
        }
        int mid=(l+r)>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        push_up(k);
    }
    void update_add(int k,int l,int r,int L,int R,int x){
        if(L<=l&&r<=R){
            add_tag(k,l,r,x,x,x,x);
            return;
        }
        push_down(k,l,r);
        int mid=(l+r)>>1;
        if(L<=mid)update_add(k<<1,l,mid,L,R,x);
        if(R>mid)update_add(k<<1|1,mid+1,r,L,R,x);
        push_up(k);
    }
    void update_min(int k,int l,int r,int L,int R,int x){
        if(x>=t[k].mxa)return;
        if(L<=l&&r<=R&&x>t[k].smx){
            t[k].sum-=1ll*t[k].cnt*(t[k].mxa-x);
            t[k].tag1-=(t[k].mxa-x);
            t[k].mxa=x;
            // add_tag(k,l,r,x-t[k].mxa,x-t[k].mxa,0,0);
            return;
        }
        push_down(k,l,r);
        int mid=(l+r)>>1;
        if(L<=mid)update_min(k<<1,l,mid,L,R,x);
        if(R>mid)update_min(k<<1|1,mid+1,r,L,R,x);
        push_up(k);
    }
    ll query_sum(int k,int l,int r,int L,int R){
        if(L<=l&&r<=R)return t[k].sum;
        push_down(k,l,r);
        int mid=(l+r)>>1;
        ll ans=0;
        if(L<=mid)ans+=query_sum(k<<1,l,mid,L,R);
        if(R>mid)ans+=query_sum(k<<1|1,mid+1,r,L,R);
        return ans;
    }
    int query_mxa(int k,int l,int r,int L,int R){
        if(L<=l&&r<=R)return t[k].mxa;
        push_down(k,l,r);
        int mid=(l+r)>>1;
        int ans=INT_MIN;
        if(L<=mid)ans=max(ans,query_mxa(k<<1,l,mid,L,R));
        if(R>mid)ans=max(ans,query_mxa(k<<1|1,mid+1,r,L,R));
        return ans;
    }
    int query_mxb(int k,int l,int r,int L,int R){
        if(L<=l&&r<=R)return t[k].mxb;
        push_down(k,l,r);
        int mid=(l+r)>>1;
        int ans=INT_MIN;
        if(L<=mid)ans=max(ans,query_mxb(k<<1,l,mid,L,R));
        if(R>mid)ans=max(ans,query_mxb(k<<1|1,mid+1,r,L,R));
        return ans;
    }
}
int main(){
    // freopen("P6242_1.in","r",stdin);
    // freopen("P6242_1.out","w",stdout);
    int n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    Segment_Tree::build(1,1,n);
    while(m--){
        int opt=read(),l=read(),r=read();
        if(opt==1){
            int x=read();
            Segment_Tree::update_add(1,1,n,l,r,x);
        }else if(opt==2){
            int x=read();
            Segment_Tree::update_min(1,1,n,l,r,x);
        }else if(opt==3){
            write(Segment_Tree::query_sum(1,1,n,l,r));
            puts("");
        }else if(opt==4){
            write(Segment_Tree::query_mxa(1,1,n,l,r));
            puts("");
        }else{
            write(Segment_Tree::query_mxb(1,1,n,l,r));
            puts("");
        }
    }
    return 0;
}
主席树
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
namespace Testify{
    il ll read(){
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*f;
    }
    il void write(ll x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    il void Write(ll x){write(x);puts("");}
    il void writE(ll x){write(x);putchar(' ');}
}
using namespace Testify;
#define M 1000050
int tim(0);
ll a[M];
int root[M];
namespace Segment_Tree{
    struct node{
        int l,r;
        ll val;
    }t[M<<5];
    int cnt(0);
    int build_tree(int l,int r){
        int rt=++cnt;
        t[rt].l=l,t[rt].r=r;
        if(l==r){
            t[rt].val=a[l];
            return rt;
        }
        int mid=(l+r)>>1;
        t[rt].l=build_tree(l,mid);
        t[rt].r=build_tree(mid+1,r);
        return rt;
    }
    int update(int pre,int l,int r,int x,int val){
        int rt=++cnt;
        t[rt]=t[pre];
        if(l==r){
            t[rt].val=val;
            return rt;
        }
        int mid=(l+r)>>1;
        if(x<=mid)t[rt].l=update(t[pre].l,l,mid,x,val);
        else t[rt].r=update(t[pre].r,mid+1,r,x,val);
        return rt;
    }
    int query(int rt,int l,int r,int x){
        if(l==r)return t[rt].val;
        int mid=(l+r)>>1;
        if(x<=mid)return query(t[rt].l,l,mid,x);
        else return query(t[rt].r,mid+1,r,x);
    }
}
signed main(){
    int n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    root[0]=Segment_Tree::build_tree(1,n);
    for(int i=1;i<=m;i++){
        int his=read(),opt=read();
        if(opt==1){
            int pos=read(),val=read();
            root[i]=Segment_Tree::update(root[his],1,n,pos,val);
        }
        else{
            int pos=read();
            Write(Segment_Tree::query(root[his],1,n,pos));
            root[i]=root[his];
        }
        // cout<<his<<endl;
        // cout<<root[i]<<" "<<root[his]<<endl;
    }
}

数论

线性筛质数
const int M=1e8+10;
int pri[M],cnt(0);
bool vis[M];
int main(){
	int n=read(),q=read();
	vis[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]){
			pri[++cnt]=i;
		}
		for(int j=1;j<=cnt&&i*pri[j]<=n;j++){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0)break;
		}
	}
	while(q--){
		int x=read();
		cout<<pri[x]<<'\n';
	}
}
高斯消元
#include <bits/stdc++.h>
using namespace std;
double a[100][100];
const double eps=1e-6;
int n;
int gauss(){
    int r=0;
    for(int i=1;i<=n;i++){
        r=i;
        for(int k=i;k<=n;k++)
            if(fabs(a[k][i])>eps){
                r=k;break;
            }
        if(r!=i)swap(a[i],a[r]);
        if(fabs(a[i][i])<eps){
            return 0;
        }
        for(int j=n+1;j>=i;j--)
            a[i][j]/=a[i][i];
        for(int k=i+1;k<=n;k++)
            for(int j=n+1;j>=i;j--)
                a[k][j]-=a[k][i]*a[i][j];
    }
    for(int i=n-1;i>=1;i--)
        for(int j=i+1;j<=n;j++)
            a[i][n+1]-=a[i][j]*a[j][n+1];
    return 1;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++){
            cin>>a[i][j];
        }
    }
    if(gauss()==1){
        for(int i=1;i<=n;i++){
            printf("%.2lf\n",a[i][n+1]);
        }
    }
    else cout<<"No Solution"<<endl;
    return 0;
}
拓展欧几里得定理
int x,y;
inline void ex_gcd(int a,int b){
    if(!b){
        x=1;
        y=0;
        return;
    }
    ex_gcd(b,a%b);
    int k=x;
    x=y;
    y=k-(a/b)*y;
    return;
}
int main(){
    int a,b;
    cin>>a>>b;
    ex_gcd(a,b);
    cout<<(x%b+b)%b<<endl;
    return 0;
}
拉格朗日插值
const int mod=998244353;
const int M=2010;
il ll fast_pow(ll x,int a){
    ll ans=1;
    while(a){
        if(a&1)ans=ans*x%mod;
        x=x*x%mod;
        a>>=1;
    }
    return ans;
}
int x[M],y[M];
signed main(){
    int n=read(),k=read();
    for(int i=1;i<=n;i++) x[i]=read(),y[i]=read();
	ll ans=0;
    for(int i=1;i<=n;i++){
        ll tmp1=y[i],tmp2=1;
        for(int j=1;j<=n;j++){
            if(j==i)continue;
            tmp1=tmp1*((k-x[j]+mod)%mod)%mod;
            tmp2=tmp2*((x[i]-x[j]+mod)%mod)%mod;
        }
        tmp1=tmp1*fast_pow(tmp2,mod-2)%mod;
        ans=ans+tmp1;
        ans%=mod;
    }
    cout<<ans;
    return 0;
} 
Dirichlet 前缀和
#include <bits/stdc++.h>
using namespace std;
#define M 20000050
#define uint unsigned int
uint seed;
inline uint getnext(){
	seed^=seed<<13;
	seed^=seed>>17;
	seed^=seed<<5;
	return seed;
}
uint a[M],p[M],cnt(0);
bool vis[M];
signed main(){
    int n;
    cin>>n>>seed;
    for(int i=1;i<=n;i++){
        a[i]=getnext();
        // cout<<a[i]<<" ";
    }
    for(int i=2;i<=n;i++){
        if(!vis[i])p[++cnt]=i;
        for(int j=1;i*p[j]<=n&&j<=cnt;j++){
            vis[i*p[j]]=1;
            if(i%p[j]==0)break;
        }
    }
    
    for(int i=1;i<=cnt;i++){
        for(int j=1;p[i]*j<=n;j++){
            a[p[i]*j]+=a[j];
        }
    }
    uint ans=0;
    for(int i=1;i<=n;i++){ans^=a[i];}
    cout<<ans;
}
卢卡斯定理
int mod;
il int fast_pow(int a,int x){
    int ans=1;
    while(x){
        if(x&1)ans=ans*a%mod;
        a=a*a%mod;
        x>>=1;
    }
    return ans;
}
int f[M],g[M];
il int get_c(int x,int y){
    return f[x]*fast_pow(f[y],mod-2)*fast_pow(f[x-y],mod-2)%mod;
}
il int lucas(int x,int y){
    if(y==0)return 1;
    return (lucas(x/mod,y/mod)*get_c(x%mod,y%mod))%mod;
}
main(void){
    int T;
    cin>>T;
    f[0]=g[0]=1;
    while(T--){
        int n,m;
        cin>>n>>m>>mod;
        for(int i=1;i<=mod;i++)f[i]=f[i-1]*i%mod;
        cout<<lucas(n+m,n)<<endl;
    }
}
拓展卢卡斯定理
int x,y;
inline void ex_gcd(int a,int b){
    if(!b){
        x=1;
        y=0;
        return;
    }
    ex_gcd(b,a%b);
    int k=x;
    x=y;
    y=k-(a/b)*y;
    return;
}
il int fast_pow(int a,int b,int p){
    int ans=1;
    while(b){
        if(b&1)ans=ans*a%p;
        a=a*a%p;
        b>>=1;
    }
    return (ans%p+p)%p;
}
il int get_inv(int a,int p){
    ex_gcd(a,p);//std::cout<<a<<" "<<p<<"  "<<x<<" "<<y<<endl;
    return (x%p+p)%p;
}
int n,m,P;
int a[M],b[M];
il int F(int n,int p,int pk){
    if(n==0)return 1;
    int arc=1,aea=1;
    for(int i=1;i<=pk;i++){
        if(i%p)arc=arc*i%pk;
    }
    arc=fast_pow(arc,n/pk,pk);
    for(int i=pk*(n/pk);i<=n;i++){
        if(__gcd(i,p)==1)aea=aea*(i%pk)%pk;
    }
    return ((F(n/p,p,pk)*arc%pk)%pk*aea%pk+pk)%pk;
}
il int G(int n,int p){
    if(n<p)return 0;
    return G(n/p,p)+n/p;
}
il int c_mod_pk(int n,int m,int p,int pk){
    int f1=F(n,p,pk);
    //cout<<F(m,p,pk)<<endl;
    int f2=get_inv(F(m,p,pk),pk);
    //cout<<F(n-m,p,pk)<<endl;
    int f3=get_inv(F(n-m,p,pk),pk);
    int k=G(n,p)-G(m,p)-G(n-m,p);
    int pg=fast_pow(p,k,pk);
    return (((f1*f2%pk)%pk*f3%pk)%pk*pg%pk)%pk;
}
il int ex_lucas(){
    int ep=P,cnt=0;
    for(int i=2;i*i<=P;i++){
        if(ep%i==0){
            int arc=1;
            while(ep%i==0){
                arc*=i;
                ep/=i;
            }
            a[++cnt]=arc;
            b[cnt]=c_mod_pk(n,m,i,arc);
        }
    }
    if(ep>1){
        a[++cnt]=ep;
        //std::cout<<ep<<endl;
        b[cnt]=c_mod_pk(n,m,ep,ep);
    }
    int ans=0;
    //cout<<cnt<<endl;
    for(int i=1;i<=cnt;i++){
        int c=P/a[i];
        //cout<<c<<" "<<a[i]<<endl;
        int cc=get_inv(c,a[i]);
        //std::cout<<"* "<<b[i]<<" "<<c<<" "<<cc<<endl;
        ans=(ans+b[i]*c%P*cc%P)%P;
    }
    return ans;
}
main(){
    cin>>n>>m>>P;
    std::cout<<ex_lucas()<<endl;
    return 0;
}
中国剩余定理
int m[10],b[10],M,ans;
int x,y;
inline void exgcd(int a,int b){
    if(b==0){
        x=1;
        y=0;
        return;
    }
    exgcd(b,a%b);
    int k=x;
    x=y;
    y=k-(a/b)*y;
    return;
}
main(){
    int n;
    M=1;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>m[i]>>b[i];
        M*=m[i];
    }
    for(int i=1;i<=n;i++){
        int c=M/m[i];
        exgcd(c,m[i]);
        ans+=b[i]*c*x%M;
    }
    cout<<(ans%M+M)%M;
}
拓展中国剩余定理
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define int __int128
#define mem(CSZPY) memset(CSZPY,0,sizeof(CSZPY))
#define MM 100050
int M,a[MM],m[MM];
int x,y;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    return;
}
il int exgcd(int a,int b){
    if(!b){
        x=1;
        y=0;
        return a;
    }
    int d=exgcd(b,a%b);
    int k=x;
    x=y;
    y=k-(a/b)*y;
    return d;
}
il int excrt(int n){
    int m1=m[1],m2,a1=a[1],a2;
    for(int i=2;i<=n;i++){
        m2=m[i],a2=a[i];
        int g=exgcd(m1,m2);
        int p=x;
        if((a2-a1)%g){return -1;}
        p=p*(a2-a1)/g;
        p=(p%(m2/g)+(m2/g))%(m2/g);
        a1=a1+m1*p;
        m1=m1*m2/g;
    }//cerr<<"======"<<endl;
    return (a1%m1+m1)%m1;
}
main(){
    int n=read();
    for(int i=1;i<=n;i++){
        m[i]=read(),a[i]=read();
    }
    write(excrt(n));
    return 0;
}
线性基
namespace Xor_Linear_Basis{
    ll a[M];
    bool zero=false;
    il void insert(ll x){
        for(int i=M;i>=0;i--){
            if((x>>i)==1)
                if(a[i]==0){a[i]=x;return;}
                else x^=a[i];
        }
        zero=true;
    }
    bool check(ll x){
        for(int i=M;i>=0;i--){
            if((x>>i)==1)
                if(a[i]==0)return false;
                else x^=a[i];
        }
        return true;
    }
    ll query_max(){
        ll ans=0;
        for(int i=M;i>=0;i--)
            if((ans^a[i])>ans)ans=ans^a[i];
        return ans;
    }
    ll query_min(){
        if(zero)return 0;
        for(int i=0;i<=M;i++)if(a[i])return a[i];
    }
    ll query_K(int k){
        if(zero)k--;
        if(!k)return 0;
        for(int i=1;i<=M;i++){
            for(int j=1;j<=i;j++){
                if(a[i]&((1ll<<j)-1))a[i]^=a[j-1];
            }
        }
        ll ans=0;
        for(int i=0;i<=M;i++)
            if(a[i]){
                if(k&1)ans^=a[i];
                k>>=1;
            }
        return ans;
    }
}

图论

dij
int dis[M];
bool vis[M];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > q;
int main(){
    int n=read(),m=read(),st=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),w=read();
        add(u,v,w);
        add(v,u,w);
    }
    memset(dis,0x7f,sizeof(dis));
    dis[st]=0;
    q.push({0,st});
    while(!q.empty()){
        pair<int,int> x=q.top();
        q.pop();
        if(vis[x.second])continue;
        vis[x.second]=1;
        for(int i=head[x.second];i;i=e[i].nxt){
            int y=e[i].v;
            if(vis[y])continue;
            if(dis[y]>x.first+e[i].w){
                dis[y]=x.first+e[i].w;
                q.push({dis[y],y});
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout<<dis[i]<<" ";
    }
    return 0;
}

SPFA and 负环
dis[1]=0;
vis[1]=1;
neg[1]=1;
q.push(1);
while(!q.empty()){
	int x=q.front();q.pop();
	vis[x]=0;
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].v;
		if(dis[x]+e[i].w<dis[y]){
			dis[y]=dis[x]+e[i].w;
			if(!vis[y]){
				vis[y]=1;
				q.push(y);
				neg[y]++;
				if(neg[y]>n){
					puts("YES");
					goto miku;
				}
			}
		}
	}
}
puts("NO");
miku:continue;
倍增lca
il void dfs(int x,int fa){
    dep[x]=dep[fa]+1;
    f[x][0]=fa;
    for(int i=1;i<=23;i++)
        f[x][i]=f[f[x][i-1]][i-1];
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(y!=fa)dfs(y,x);
    }
}
il int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=23;i>=0;i--){
        if(dep[f[x][i]]>=dep[y]){
            x=f[x][i];
        }
    }
    if(x==y)return x;
    for(int i=23;i>=0;i--){
        if(f[x][i]!=f[y][i]){
            x=f[x][i],y=f[y][i];
        }
    }
    return f[x][0];
}
树链剖分
int siz[M],dep[M],f[M],top[M],son[M];
il void dfs1(int x,int fa){
    dep[x]=dep[fa]+1;
    f[x]=fa;
    siz[x]=1;
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(y!=fa){
            dfs1(y,x);
            siz[x]+=siz[y];
            if(!son[x] || siz[y]>siz[son[x]]){
                son[x]=y;
            }
        }
    }
}
il void dfs2(int x,int tpx){
    top[x]=tpx;
    if(!son[x])return;
    dfs2(son[x],tpx);
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(y!=f[x] && y!=son[x]){
            dfs2(y,y);
        }
    }
}
il int lca(int x,int y){
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        x=f[top[x]];
    }
    return dep[x]<dep[y]?x:y;
}
int main(){
    int n,m,s;
    cin>>n>>m>>s;
    for(int i=1;i<n;i++){
        int u,v;
        cin>>u>>v;
        add_edge(u,v);
        add_edge(v,u);
    }
    dfs1(s,0);
    dfs2(s,s);
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        cout<<lca(x,y)<<endl;
    }
    return 0;
}
点双
struct edge{
    int u,v,next;
};
edge e[M];
int head[M],cnt;
void add_edge(int u,int v){
    e[++cnt].u=u;
    e[cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
int dfn[M],low[M],stk[M],ecnt,dcc,top;
vector<int> ans[M];
void tarjan(int x,int fa){
    dfn[x]=low[x]=++ecnt;
    stk[++top]=x;
    if(x==fa && !head[x]){
        ans[++dcc].push_back(x);
        return;
    }
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(!dfn[y]){
            tarjan(y,x);
            low[x]=min(low[x],low[y]);
            if(low[y]>=dfn[x]){
                ++dcc;
                int yy;
                do{
                    yy=stk[top--];
                    ans[dcc].push_back(yy);
                }while(yy!=y);
                ans[dcc].push_back(x);
            }
        }
        else{
            low[x]=min(low[x],dfn[y]);
        }
    }
}
int main(){
    cnt=1;
    int n=read(),m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        if(u==v){
            continue;
        }
        add_edge(u,v);
        add_edge(v,u);
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i])tarjan(i,i);
    }
    cout<<dcc<<endl;
    for(int i=1;i<=dcc;i++){
        cout<<ans[i].size()<<" ";
        for(int j=0;j<ans[i].size();j++){
            cout<<ans[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
边双
struct edge{
    int v,next;
};
edge e[M];
int head[M],ent=1;
void add_edge(int u,int v){
    e[++ent].v=v;
    e[ent].next=head[u];
    head[u]=ent;
}
int dfn[M],low[M],stk[M],tot,dnt,top;
vector<int> dcc[M];
void tarjan(int x,int in_edge){
    dfn[x]=low[x]=++tot;
    stk[++top]=x;
    for(int i=head[x];i;i=e[i].next){
        int y=e[i].v;
        if(!dfn[y]){
            tarjan(y,i);
            low[x]=min(low[x],low[y]);
        }
        else if(i!=(in_edge^1)){
            low[x]=min(low[x],dfn[y]);
        }
    }
    if(low[x]==dfn[x]){
        int y;dnt++;
        do{
            y=stk[top--];
            dcc[dnt].push_back(y);
        }while(y!=x);
    }
}
int main(){
    int n=read(),m=read();
    for(int i=1;i<=m;i++){
        int a=read(),b=read();
        add_edge(a,b);
        add_edge(b,a);
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i])tarjan(i,0);
    }
    cout<<dnt<<endl;
    for(int i=1;i<=dnt;i++){
        cout<<dcc[i].size()<<" ";
        for(int j=0;j<dcc[i].size();j++){
            cout<<dcc[i][j]<<" ";
        }
        puts("");
    }
    return 0;
}
Edmonds-Karp
struct node{
    int w,v,nxt;
}e[M<<1];
int head[M],cnt=1;
il void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
int n,m,s,t;
int pre[M],dis[M];
queue<int> q;
il int bfs(){
    for(int i=1;i<=n;i++)pre[i]=0,dis[i]=1145141919;
    q.push(s);
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;
            if(pre[y]||y==s||!e[i].w)continue;
            q.push(y);
            dis[y]=min(dis[x],e[i].w);
            pre[y]=i;
        }
    }
    if(!pre[t])return -1;
    return dis[t];
}
main(){
    n=read(),m=read(),s=read(),t=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),w=read();
        add(u,v,w);
        add(v,u,0);
    }
    ll ans=0;
    while(true){
        int k=bfs();
        if(k==-1)break;
        ans+=k;
        int now=t;
        while(now!=s){
            e[pre[now]].w-=k;
            e[pre[now]^1].w+=k;
            now=e[pre[now]^1].v;
        }
    }
    cout<<ans;
    return 0;
}
Dinic
#include <bits/stdc++.h>
using namespace std;
#define il inline
#define ll long long
#define int long long
il ll read(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
const int M=5010;
const ll inf=1ll<<60;
struct node{
    int v,nxt;
    ll w;
}e[M<<1];
int head[M],cnt=1;
il void add(int u,int v,ll w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
int n,m,s,t;
int dep[M],now[M];
queue<int> q;
il bool bfs(){
    while(!q.empty())q.pop();
    for(int i=1;i<=n;i++)dep[i]=-1;
    dep[s]=0;
    q.push(s);
    now[s]=head[s];
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=e[i].nxt){
            int y=e[i].v;  
            if(e[i].w>0&&dep[y]==-1){
                q.push(y);
                now[y]=head[y];
                dep[y]=dep[x]+1;
                if(y==t)return 1;
            }
        }
    }
    return 0;
}
int dfs(int x,ll sum){
    if(x==t)return sum;
    ll k,flow=0;
    for(int i=now[x];i&&sum;i=e[i].nxt){
        now[x]=i;
        int y=e[i].v;
        if(e[i].w>0&&(dep[y]==dep[x]+1)){
            k=dfs(y,min(sum,e[i].w));
            if(k==0)dep[y]=-1;
            e[i].w-=k;
            e[i^1].w+=k;
            flow+=k;
            sum-=k;
        }
    }
    return flow;
}
main(){
    n=read(),m=read(),s=read(),t=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read();
        ll w=read();
        add(u,v,w);
        add(v,u,0);
    }
    ll ans=0;
    while(bfs())ans+=dfs(s,inf);
    cout<<ans;
    return 0;
}

字符串

字符串哈希
#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
ull a[10010];
char s[10010];
ull Hash(char *s){
    ull P=131,H=0;
    int len=strlen(s);
    for(int i=0;i<len;i++)H=H*P+s[i]-'a'+1;
    return H;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>s;
        a[i]=Hash(s);
    }
    int ans=0;
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++){if(a[i-1]!=a[i])ans++;}
    cout<<ans<<endl;
    return 0;   
}
马拉车
#include <bits/stdc++.h>
using namespace std;
#define S 50000050
char a[S],s[S<<1];
int len;
int p[S];
inline void manacher(){
    s[0]='$',s[1]='#';
    for(int i=0;i<len;i++){
        s[(i<<1)+2]=a[i];
        s[(i<<1)+3]='#';
    }
    len=(len<<1)+2;
    s[len]='@';
    int maxright=0,mid;
    for(int i=1;i<len;i++){
        if(i<maxright)p[i]=min(p[(mid<<1)-i],p[mid]+mid-i);
        else p[i]=1;
        for(;s[i+p[i]]==s[i-p[i]];++p[i]);
        if(p[i]+i>maxright){
            maxright=p[i]+i;
            mid=i;
        }
    }
}
int main(){
    cin>>a;
    len=strlen(a);
    int ans=1;
    manacher();
    for(int i=0;i<len;i++){
        ans=max(ans,p[i]);
    }
    cout<<ans-1<<endl;
    return 0;
}
AC自动机
struct node{
    int son[30];
    int fail,end;
}t[M];
int cnt(0);
il void Insert(char *s){
    int pos=0;
    for(int i=0;s[i];i++){
        int ch=s[i]-'a';
        if(t[pos].son[ch]==0)t[pos].son[ch]=cnt++;
        pos=t[pos].son[ch];
    }
    t[pos].end++;
    return;
}
il void get_Fail(){
    queue<int> q;
    for(int i=0;i<26;i++){//第一层入队
        if(t[0].son[i])q.push(t[0].son[i]);
    }
    while(!q.empty()){
        int pos=q.front();
        q.pop();
        for(int i=0;i<26;i++){
            if(t[pos].son[i]){
                t[t[pos].son[i]].fail=t[t[pos].fail].son[i];
                q.push(t[pos].son[i]);
            }
            else t[pos].son[i]=t[t[pos].fail].son[i];
        }
    }
}
il int query(char *s){
    int ans=0;
    int pos=0;
    for(int i=0;s[i];i++){
        int ch=s[i]-'a';
        pos=t[pos].son[ch];
        int tmp=pos;
        while(tmp&&t[tmp].end!=-1){
            ans+=t[tmp].end;
            t[tmp].end=-1;
            tmp=t[tmp].fail;
        }
    }
    return ans;
}
char str[M];
int main(){
    cnt=1;
    int n=read();
    while(n--){
        cin>>str;
        Insert(str);
    }
    get_Fail();
    cin>>str;
    cout<<query(str)<<endl;
    return 0;
}
KMP
#include <bits/stdc++.h>
using namespace std;
char s1[1000010];
char s2[1000010];
int Next[1000010];
int len;
inline void get_next(){
    len=strlen(s2);
    Next[0]=0;Next[1]=0;
    for(int i=1;i<len;i++){
        int j=Next[i];
        while(j&&s2[i]!=s2[j])j=Next[j];
        if(s2[i]==s2[j])Next[i+1]=j+1;
        else Next[i+1]=j;
    }
}
void write(int x){
    if(x<0)putchar('-'),x=-x;
    if(x>9)write(x/10);
    putchar(x%10+'0');
    return;
}
int main(){
    cin>>s1>>s2;
    get_next();
    int j=0;
    int len_main=strlen(s1);
    for(int i=0;i<len_main;i++){
        while(j&&s1[i]!=s2[j])j=Next[j];
        if(s1[i]==s2[j])j++;
        if(j==len){write(i-len+2);puts("");}
    }
    for(int i=1;i<=len;i++){write(Next[i]);printf(" ");}
    return 0;
}
posted @ 2023-10-11 07:04  CCComfy  阅读(44)  评论(3编辑  收藏  举报