板子们(不定时更新)

板子们

早期写代码大括号竟然换行,QAQ,我都没法原谅我自己。

emmm,把我目前能想到的,会的,全写上了。

如果再想到还会补的。

数论

exgcd

#include<iostream>
using namespace std ;
int a,b,x,y;
int exgcd(int a,int b,int &x,int &y){
	if(b==0){
		x=1;y=0;
		return a;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
int main(){
	cin>>a>>b;
	exgcd(a,b,x,y);
	cout<<((x%b)+b)%b;
	return 0;
}

快速幂(取模)

#include<iostream>
#define ll long long 
using namespace std;
ll ksm(ll a,ll b,ll p){
	ll ans=1;
	while(b!=0){
		if(b&1){
			ans=ans*a%p;
		}
		a=a*a%p;
		b>>=1;
	}
	return ans;
}

ll b,a,ans,p;

int main(){
	cin>>a>>b>>p;
	ans=ksm(a,b,p);
	ans%=p;//好习惯
	cout<<a<<'^'<<b<<" mod "<<p<<'='<<ans;
}

就是0次方%1的情况,要最后在%一次,不然会被卡(像我一直有这种好习惯)

CRT

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n;
ll N=1;
ll a[20],b[20];
ll ans=0;
ll qaq(ll a,ll b,ll mod){
    ll ans=0;
    while(b>0)
    {
        if(b&1) ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ans;
}

void exgcd(ll a,ll b,ll &x,ll &y){
	if(b==0){x=1,y=0;return;} 
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}

void CRT()
{
    ll x,y;
    for(int i=1;i<=n;++i){
        ll tp=N/b[i];
        exgcd(tp,b[i],x,y);
        x=(x%b[i]+b[i])%b[i];
        ans=(ans+qaq(qaq(tp,x,N),a[i],N))%N;
    }
}

int main(){    
    cin>>n;
    for(int i=1;i<=n;++i){
		cin>>a[i];	
	} 
    for(int i=1;i<=n;++i){
		cin>>b[i];
		N*=b[i];
		a[i]=((a[i]%b[i])+b[i])%b[i];
	} 
	CRT();
    cout<<((ans%N)+N)%N;
    return 0;
}

裴蜀定理

#include<iostream>
#include<cstdio>
using namespace std;
int n;
int ans=0;
int a;
inline void read(int &x){
	int f=1;x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();}
	while(s>='0'&&s<='9'){ x=x*10+s-'0';s=getchar();} 
	x*=f;
}

inline int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

int main(){
	read(n);
	for(int i=1;i<=n;i++){
		read(a);
		if(a<0)	a=-a;
		ans=gcd(ans,a);
	}
	cout<<ans<<endl;
} 

有理数取余

#include<cmath> 
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
/*----------------HUI----------------*/

inline void read(int &x){
    x=0;int f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=(x*10+s-'0')%19260817;s=getchar();} 
    x*=f;
}

inline int ksm(int x,int y=19260815){
    int ans=1;
    while(y){
        if(y&1) ans=ans*x%19260817;
        x=x*x%19260817;
        y>>=1;
	}
    return ans;
}
int a,b;
signed main(){
    read(a);read(b);
    int sum=(a*ksm(b))%19260817; 
    if(sum==0){
        cout<<"Angry!"<<endl;
    }
    else{
        cout<<sum<<endl;
    }
    return 0;
}

乘法逆元

快速幂:

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long 
using namespace std;

ll n,p;

ll ksm (ll a,ll b=p-2){
	ll ans=1;
	while(b>0){
		if(b&1){
			ans=ans*a%p;
		}
		a=a*a%p;
		b>>=1; 
	}
	return ans;
} 

int main(){
	ios::sync_with_stdio(false);
	cin>>n>>p;
	for(int i=1;i<=n;i++) {
		cout<<ksm(i)<<endl;
	}
	return 0;
}

拓展欧几里德

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long 
using namespace std;

ll n,p;
ll x,y;

void exgcd(ll a,ll b,ll &x,ll &y){
	if(b==0){
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
} 

int main(){
	ios::sync_with_stdio(false);
	cin>>n>>p;
    for(int i=1;i<=n;i++){
        exgcd(i,p,x,y);
		cout<<((x%p)+p)%p<<endl;	
	}
	return 0;
}

线性递推

(没事就别用cin,cout,我线性递推因此T3个点)

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long 

using namespace std;

ll n,p;
ll inv[3050500];

int main(){
	cin>>n>>p;
	inv[1]=1;
	printf("1\n");
	for(int i=2;i<=n;i++){
		inv[i]=(p-p/i)*inv[p%i]%p;
		printf("%lld\n",inv[i]);
	}
	return 0;
}

卢卡斯定理

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define ll long long 
ll t,n,m,p;
ll a[100007],b[100007];

ll lucas(int x,int y)
{
    if(x<y) return 0;
    else if(x<p) return b[x]*a[y]*a[x-y]%p;
    else return lucas(x/p,y/p)*lucas(x%p,y%p)%p;
}

int main()
{
    scanf("%lld",&t);
    while(t)
    {
        scanf("%lld%lld%lld",&n,&m,&p);
        a[0]=a[1]=b[0]=b[1]=1;
        for(int i=2;i<=n+m;i++) b[i]=b[i-1]*i%p;
        for(int i=2;i<=n+m;i++) a[i]=(p-p/i)*a[p%i]%p;
        for(int i=2;i<=n+m;i++) a[i]=a[i-1]*a[i]%p;
        printf("%lld\n",lucas(n+m,m));
        t--;
    }
    return 0;
}

欧拉筛全家桶(prime+phi+d+sd)

const int N=1e5+5;
bool mark[N];
int prim[N],d[N],num[N];
long long sd[N],sp[N];
int cnt;
void initial()
{
    cnt=0;
    d[1]=1;
	sd[1]=1;
    for(int i=2;i<N;++i)
    {
        if (!mark[i])
        {
            prim[++tot]=i;
		phi[i]=i-1;
		sd[i]=i+1;
            sp[i]=i+1;
            num[i]=1;
            d[i]=2;
        }
        for(int j=0;j<cnt&&i*prim[j]<N;++j)
        {
            mark[i*prim[j]]=1;
            if (!(i%prim[j]))
            {
                num[i*prim[j]]=num[i]+1;
                d[i*prim[j]]=d[i]/(num[i]+1)*(num[i*prim[j]]+1);
			sp[i*prim[j]]=sp[i]*prim[j]+1;
                sd[i*prim[j]]=sd[i]/sp[i]*sp[i*prim[j]];
			phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            d[i*prim[j]]=d[i]*d[prim[j]];
            num[i*prim[j]]=1;
		sd[i*prim[j]]=sd[i]*sd[prim[j]];
            sp[i*prim[j]]=1+prim[j];
		phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}

矩阵加速

#include<cstdio>
#include<iostream>
#include <cstring>
using namespace std;
#define ll long long
#define il inline
#define r register
#define mod 1000000007
ll t;
ll n;
struct node
{
    ll ju[5][5];
}chu,e,D;
node multiply(node a,node b)
{
    node t;
    for(r ll i=1;i<=3;i++)
        for(r ll j=1;j<=3;j++)
            t.ju[i][j]=0;
    for(r ll i=1;i<=3;i++)
        for(r ll j=1;j<=3;j++)
            for(r ll k=1;k<=3;k++)
            {
                t.ju[i][j]+=(a.ju[i][k]%mod)*(b.ju[k][j]%mod)%mod;
                t.ju[i][j]%=mod;
            }
    return t;
}
node ksm(node x,ll y)
{
    node re=D;
    while(y)
    {
        if(y&1) 
            re=multiply(re,x);
        x=multiply(x,x);
        y>>=1;
    }
    return re;
}
int main()
{
    scanf("%lld",&t);
    chu.ju[1][1]=1;
    chu.ju[1][2]=1;
    chu.ju[1][3]=1;
    e.ju[1][3]=1;
    e.ju[2][1]=1;
    e.ju[3][2]=1;
    e.ju[3][3]=1;
    for(r ll i=1;i<=3;i++)
        D.ju[i][i]=1;
    while(t--)
    { 
        scanf("%lld",&n);
        if(n<=3)
        {
            printf("1\n");
            continue;
        }
        node ans=multiply(chu,ksm(e,n-3));
        printf("%lld\n",ans.ju[1][3]%mod);
    }
    return 0;
}

矩阵快速幂

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int  long long
#define IL inline
#define R register
const int mod=1e9+7;
using namespace std;
int n,k;
struct node{
    int ju[120][120];
    node(){
        memset(ju,0,sizeof ju);
    }
    friend node operator * (const node &a,const node &b)
    {
        node t;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                for(int k=1;k<=n;k++){
                    (t.ju[i][j]+=a.ju[i][k]*b.ju[k][j])%=mod;
                }
        return t;
    }
    void e()
    {
        memset(ju,0,sizeof ju);
        for(int i=1;i<=n;i++)
        {
            ju[i][i]=1;
        }
    }
    void out(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                printf("%d%c",ju[i][j],j==n?'\n':' ');
            }
    }
}chu,E;

node ksm(node x,int y){
    E.e();
    while(y)
    {
        if(y&1)
            E=E*x;
        x=x*x;
        y>>=1;
    }
    return E;
}

signed main()
{
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>chu.ju[i][j];
    (ksm(chu,k)).out();
    return 0;
}

nim游戏

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
#define IL inline
#define R register
using namespace std;

int main(){
    int T;
    int n;
    int x;
    cin>>T;
    while(T--){
        cin>>n;
        int ans=0;
        for(int i=1;i<=n;i++){
            cin>>x;
            ans=ans^x;
        }
        if(ans){
            cout<<"Yes"<<endl;
        }
        else{
            cout<<"No"<<endl;
        }
    }
    return 0;
}

图论

最小生成树

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

int n,m,ans=0;
int fa[105050];
struct node{
    int u,v,w;
}qwq[205050];

inline void read(int &x){
    x=0;int f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 
    x*=f;
}

inline bool cmp(node a,node b){
    return a.w<b.w;
}

inline int find(int x){
    if(fa[x]==x){
        return x;
    }
    return fa[x]=find(fa[x]);
}

int main(){
    read(n);read(m);
    for(int i=1;i<=n;i++){
        fa[i]=i;
    }
    for(int i=1;i<=m;i++){
        read(qwq[i].u);read(qwq[i].v);read(qwq[i].w);
    }
    sort(qwq+1,qwq+1+m,cmp);
    for(int i=1;i<=m;i++){
        if(find(qwq[i].u)!=find(qwq[i].v)){
            fa[find(qwq[i].u)]=find(qwq[i].v);
            ans+=qwq[i].w;
        }
    }
    cout<<ans<<endl;
    return 0;
}

二分图

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

int ans=0;
int x,y;
int n,m,e;
struct node{
    int u;
    int v;
}qwq[305000];
int head[305050];
int tot=0;
bool vis[305050];
int to[305050];

inline void add(int x,int y){
    qwq[++tot].u=head[x];
    qwq[tot].v=y;
    head[x]=tot;
}

inline bool find(int x){
    for(int i=head[x];i;i=qwq[i].u){
        int v=qwq[i].v;
        if(vis[v]==0){
            vis[v]=1;
            if(to[v]==0||find(to[v])==1){
                to[v]=x;
                return 1;
            }	
        }
    }
    return 0;
}

int main(){
    cin>>n>>m>>e;
    for(int i=1;i<=e;i++){
        cin>>x>>y;
        if(y>m||x>n){
            continue;
        }
        add(x,y);
    }
    for(int i=1;i<=n;i++){
        memset(vis,0,sizeof vis);
        ans+=find(i);
    }
    cout<<ans<<endl;
}

spfa判负环(你就当是差分约束也行)

#include<queue> 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

/*----------------HUI----------------*/

int T;
int n,m;
int head[105050],tot=0;
int toto[105050];
int dis[105050];
int vis[105050];
int x,y,z;
struct node{
	int u,v,w;
}qwq[105050];
queue<int>q;


inline void add(int x,int y,int z){
	qwq[++tot].u=head[x];
	qwq[tot].v=y;
	qwq[tot].w=z;
	head[x]=tot;
}

inline void clear(){
	tot=0;
	memset(head,0,sizeof head);
	memset(toto,0,sizeof toto);
	memset(dis,0x3f,sizeof dis);
	memset(vis,0,sizeof vis);
}

inline bool spfa(int x){
	q.push(x);
	dis[x]=0;
	vis[x]=1;
	toto[x]++; 
	while(!q.empty()){
		int u=q.front();q.pop();vis[u]=0;
	    for(int i=head[u];i;i=qwq[i].u){
	    	int v=qwq[i].v;
	    	if(dis[v]>dis[u]+qwq[i].w){
	    		dis[v]=dis[u]+qwq[i].w;
				if(vis[v]==0){
	    			vis[v]=1;
	    			toto[v]++;
	    			if(toto[v]>n){
	    				return 1;
	    			}
	    			q.push(v);
	    	    }	
	    	}	    
		}
	}
	return 0;
}

int main(){
	cin>>T;
	while(T--){
		clear();
		cin>>n>>m;
		for(int i=1;i<=m;i++){
			cin>>x>>y>>z;
			if(z<0){
				add(x,y,z);	
			}
			else{
				add(x,y,z);
				add(y,x,z);	
			}
		}
		if(spfa(1)){
			cout<<"YE5"<<endl;
		}
		else{
			cout<<"N0"<<endl;
		}
	}
	return 0;
}

2-sat

#include<cmath>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define IL inline
#define R register
using namespace std;

inline void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
/*名为DracoM*/

int n,dfn[5050500],low[5050500],belong[5050500],stk[5050500];
int top;
int a; 
int m;
int b,c,d;
int f,e;
int head[5050500];
int tot=0;
int idx,cnt,ins[5050500];
int ans=0;
bool vis[5050500];
struct node{
	int u,v;
}qwq[5050500];

inline void add(int x,int y){
	qwq[++tot].u=head[x];
	qwq[tot].v=y;
	head[x]=tot;
}

inline void tarjan(int x){
	dfn[x]=low[x]=++idx;
	stk[++top]=x;vis[x]=true;
	for(int i=head[x];i;i=qwq[i].u){
		if(!dfn[qwq[i].v]){
			tarjan(qwq[i].v);
            low[x]=min(low[x],low[qwq[i].v]);
		}
		else if (vis[qwq[i].v]) low[x]=min(low[x],dfn[qwq[i].v]);
	}
	if(dfn[x]==low[x]){
		cnt++;
		int now=-1;
	    while(x!=now)
	    {
	   	    now=stk[top--];
	   	    belong[now]=cnt;
	   	    vis[now]=false;
	    }
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>a>>b>>c>>d;
        int e=b^1;
        int f=d^1;
        add(a+e*n,c+d*n);
        add(c+f*n,a+b*n);
	}
	for(int i=1;i<=(n<<1);i++)
	{
		if(dfn[i])continue;
		tarjan(i);
	}
	for(int i=1;i<=n;i++){
		if(belong[i+n]==belong[i]){
			cout<<"IMPOSSIBLE"<<endl;
		    return 0;
		}
	}
	cout<<"POSSIBLE"<<endl;
	for(int i=1;i<=n;i++)
		printf("%d ",belong[i]>belong[i+n]);
	return 0;
}

LCA

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxlog = 20;
const int maxn = 550000;

int n, m, s;
int root;
int fa[maxn][maxlog];
int deep[maxn];
int head[maxn];
int cnt;
struct Edge{
    int next;
    int to;
}e[2*maxn];
void add(int u, int v){
    e[cnt].to = v;
    e[cnt].next = head[u];
    head[u] = cnt++;
}
void dfs(int u, int p, int d){
    fa[u][0] = p;
    deep[u] = d;
    for(int i = head[u]; i != -1; i = e[i].next)
        if(e[i].to != p) dfs(e[i].to, u, d+1);
}
void init(){
    dfs (root, -1, 0);
    for(int k = 0; k + 1 < maxlog; k++)
    {
        for(int v = 1; v <= n; v++)
        if(fa[v][k] < 0) fa[v][k+1] = -1;
        else fa[v][k+1] = fa[fa[v][k]][k];
    }
}
int lca(int u, int v)
{
    if(deep[u] > deep[v]) swap(u, v);
    for(int k = 0; k < maxlog; k++)
    {
        if(deep[v] == deep[u]) break;
        if((deep[v] - deep[u]) >> k & 1)
        {
        v = fa[v][k];
        }
    }
    
    if(u == v) return u;

    for(int k = maxlog - 1; k >= 0; k--)
    {
        if(fa[v][k] != fa[u][k])
        {
            u = fa[u][k];
            v = fa[v][k];
        }
    }
    return fa[u][0];
}
int main(){
    memset(head,-1,sizeof(head)); 
    int a,b;
    scanf("%d%d%d",&n,&m,&root);
    for(int i = 1; i < n; i++){
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    init();
    for(int i = 1; i <= m; i++){
        int u,v,a;
        scanf("%d%d",&u,&v);
        a = lca(u,v);
        printf("%d\n",a);
    }
    return 0;    
}

DIJ求最短路

#include<bits/stdc++.h>
#define int long long
using namespace std;


int dis[205050];
bool vis[205050];
struct node{
    int u,v,w;
}qwq[205050];
int tot=0;
int head[205050];
int n,m,s;

void add(int x,int y,int z)
{
    qwq[++tot].u=head[x];
    qwq[tot].v=y;
    qwq[tot].w=z;
    head[x]=tot;
}

priority_queue<pair<int,int>,vector<pair<int,int> >, greater<pair<int ,int > > >q;

void dij(int s){
    memset(dis,0x7f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    q.push(make_pair(0,s));
    dis[s]=0;
    while(!q.empty()){
        pair<int,int> tp=q.top();
        q.pop();
        if(vis[tp.second]==1){
            continue;
        }
        vis[tp.second]=1;
        for(int i=head[tp.second];i;i=qwq[i].u){
            int v=qwq[i].v;
            if(dis[v]>dis[tp.second]+qwq[i].w){
                dis[v]=dis[tp.second]+qwq[i].w;
                q.push(make_pair(dis[v],v));
            }
        }    
    }
}

signed main(){
    cin>>n>>m>>s;
    int x,y,z;
    for(int i=1;i<=m;i++){
        cin>>x>>y>>z;
        add(x,y,z);
    }
    dij(s);
    for(int i=1;i<=n;i++){
        cout<<dis[i]<<' ';
    }
    return 0;
}

倍增Floyd

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll vis[20500];
ll w[2050][2050];
ll n,tot,m,s,t;
struct node{
    ll f[205][205];
    node(){memset(f,0x3f,sizeof f);}
}ans;
node mul(node a,node b){
    node re;
    for(ll k=1;k<=tot;k++)
        for(ll i=1;i<=tot;i++)
            for(ll j=1;j<=tot;j++)
                if(re.f[i][j]>a.f[i][k]+b.f[k][j])
                    re.f[i][j]=a.f[i][k]+b.f[k][j];
    return re;
}
ll ksm(ll k){
    node re;
    for(ll i=1;i<=tot;i++)
        re.f[i][i]=0;
    while(k){
        if(k&1) re=mul(re,ans);
        ans=mul(ans,ans);
        k>>=1;
    }
    return re.f[vis[s]][vis[t]];
}
int main(){
    scanf("%lld%lld%lld%lld",&n,&m,&s,&t);
    for(ll i=1;i<=m;i++){
        ll c,a,b;
        scanf("%lld%lld%lld",&c,&a,&b);
        if(!vis[a]) vis[a]=++tot;
        if(!vis[b]) vis[b]=++tot;
        ans.f[vis[a]][vis[b]]=ans.f[vis[b]][vis[a]]=min(ans.f[vis[a]][vis[b]],c);
    }
    printf("%lld\n",ksm(n));
    return 0;
}

次短路

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<string>
using namespace std;
#define LL long long
LL n,m;
struct node{
    LL to,nxt,dis;
}e[300500];
LL head[100020],tot;
LL dis1[100020],dis2[100020];
void add(LL u,LL v,LL val){
    e[++tot].nxt=head[u];
    e[tot].to=v;
    e[tot].dis=val;
    head[u]=tot;
}
typedef pair<LL,LL> P;
priority_queue<P,vector<P>,greater<P> > q;
void DIJ(){
    memset(dis1,0x3f,sizeof dis1);
    memset(dis2,0x3f,sizeof dis2);
    dis1[1]=0;
    q.push(make_pair(0,1)); 
    while(!q.empty()){
        P u=q.top();
        q.pop();
        LL x=u.second,d=u.first;
        if(dis2[x]<d)continue;
        for(LL i=head[x];i;i=e[i].nxt){
            LL d2=d+e[i].dis,v=e[i].to;
            if(dis1[v]>d2){
                dis2[v]=dis1[v];
                swap(dis1[v],d2);
                q.push(make_pair(dis1[v],v));
            }
            if(dis2[v]>d2&&dis1[v]<d2){
                dis2[v]=d2;
                q.push(make_pair(dis2[v],v));
            }
        }
    }
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(LL i=1;i<=m;i++){
        LL x,y,z;
        scanf("%lld%lld%lld",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    DIJ();
    printf("%lld\n",dis2[n]);
    return 0;
}

分层图最短路

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define mp make_pair
#define S second
#define F first
using namespace std;
int x,y,z;
int s,t,n,m,k;
struct node{
    int u,v,w;
}qwq[205050];
int tot=0,head[205050];
int dis[205050][21],vis[205050][21];

void add(int x,int y,int z){
    qwq[++tot].u=head[x];
    qwq[tot].v=y;
    qwq[tot].w=z;
    head[x]=tot;
}
void Dijkstra(){
    memset(dis,0x3f,sizeof dis);
    priority_queue<pair<int ,pair<int ,int > > > pq;
    pair<int,int> u;
    int v;
    dis[s][0]=0;
    pq.push(mp(0,mp(s,0)));
    while(!pq.empty()){
        u=pq.top().S;
        pq.pop();
        if(vis[u.F][u.S]){
            continue;
        }
        vis[u.F][u.S]=1;
        for(int i=head[u.F];i;i=qwq[i].u){
            v=qwq[i].v;
            if(dis[v][u.S]>dis[u.F][u.S]+qwq[i].w){
                dis[v][u.S]=dis[u.F][u.S]+qwq[i].w;
                pq.push(mp(-dis[v][u.S],mp(v,u.S)));
            }
            if(u.S+1<=k&&dis[v][u.S+1]>dis[u.F][u.S]){
                dis[v][u.S+1]=dis[u.F][u.S];
                pq.push(mp(-dis[v][u.S+1],mp(v,u.S+1)));
            }
        }
    }
}

int ans=0x3f3f3f3f;
signed main(){
    cin>>n>>m>>k;
    cin>>s>>t;
    for(int i=1;i<=m;i++){
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }	
    Dijkstra();
    cout<<dis[t][k]<<endl;
    // cout<<ans<<endl;
}

割点

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

int n,m;
int x,y;
struct node{
    int u,v;
}qwq[1050050];
int tot=0,head[1050050];
int dfn[1050050],low[1005050];
bool ans[1050050];
int idx=0;

void add(int x,int y){
    qwq[++tot].u=head[x];
    qwq[tot].v=y;
    head[x]=tot;
}

void tarjan(int x,int fa){
    int sum=0;
    dfn[x]=low[x]=++idx;
    for(int i=head[x];i;i=qwq[i].u){
        int v=qwq[i].v;
        if(!dfn[v]){
            tarjan(v,fa);
            if(low[v]>=dfn[x]&&x!=fa){
                ans[x]=1;
            }
            if(x==fa){
             	sum++;
            }
            low[x]=min(low[x],low[v]);
        }
        low[x]=min(low[x],dfn[v]);
    } 
    if(x==fa&&sum>1) ans[x]=1;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]==0){
            tarjan(i,i);
        }
    }
    int cntt=0;
    for(int i=1;i<=n;i++){
        if(ans[i]) 
            cntt++;
    }
    printf("%d\n",cntt);
    for(int i=1;i<=n;i++){
        if(ans[i]) 
            printf("%d ",i);
    }
    return 0;
}

缩点

#include<cmath>
#include<queue>
#include<string>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define IL inline
#define R register
using namespace std;

inline void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
/*名为DracoM*/
queue<int>q;
int n,m;
int x,y;
int top;
int cnt;
int idx;
int ans;
int val[105050];
int dfn[105050];
int dis[105050];
int low[105050];
int stk[105050];
int val2[105050];
bool vis[105050];
int belong[105050];
int head[105050],tot=0;
int head1[105050];
struct node{
    int u,v;
} qwq[105050],qaq[105050];

inline void add (int x,int y){
    qwq[++tot].u=head[x];
    qwq[tot].v=y;
    head[x]=tot;
}

inline void add1(int x,int y){
    tot++;
    qaq[tot].v=y;
    qaq[tot].u=head1[x];
    head1[x]=tot;
}

IL void spfa(int x)
{
    memset(vis ,0 ,sizeof vis);
    for(int i=1;i<=n;i++)
    {
        dis[i]=-2147483644;
    }
    q.push(x);
    dis[x]=val2[x];
    vis[x]=1;
    while(!q.empty()){
        int tp=q.front();
        q.pop();
        vis[tp]=0;
        for(int i=head1[tp];i;i=qaq[i].u){
            int v=qaq[i].v;
            if(dis[v]<dis[tp]+val2[v])
            {
                dis[v]=dis[tp]+val2[v];
                if(vis[v]==0){
                    vis[v]=1;
                    q.push(v);
                }
            
            }
        }
    }
    for(int i=1;i<=cnt;i++)   ans=max(ans,dis[i]);
}

inline void tarjan(int x){
    dfn[x]=low[x]=++idx;
    stk[++top]=x;vis[x]=true;
    for(int i=head[x];i;i=qwq[i].u){
        if(!dfn[qwq[i].v]){
            tarjan(qwq[i].v);
            low[x]=min(low[x],low[qwq[i].v]);
        }
        else if(vis[qwq[i].v]) low[x]=min(low[x],dfn[qwq[i].v]);
    }
    if(dfn[x]==low[x]){
        cnt++;
        int now=-1;
        while(x!=now){
            now=stk[top--];
            val2[cnt]+=val[now];
            belong[now]=cnt;
            vis[now]=false;
        }
    }
}

inline void shink_point(){
    tot=0;int t;
    for(int i=1;i<=n;i++)
    {
    for(int j=head[i];j;j=qwq[j].u)
        {
        	t=qwq[j].v;
        	if(belong[i]!=belong[t])
        	    add1(belong[i],belong[t]);
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>val[i];
    }
    for(int i=1;i<=m;i++){
        cin>>x>>y;
        add(x,y);
    }
    for(int i=1;i<=n;i++){
        if(dfn[i]){
            continue;
        }
        tarjan(i);
    }
    shink_point();
    for(int i=1;i<=cnt;i++){
        spfa(i);
    }
    cout<<ans<<endl;
    return 0;
}

数据结构

手写栈

/*主要为了单调栈准备的*/
struct node{
	int st[1005050];
	int tp;
	inline void pop() {tp--;}
	inline void push(int x) {st[++tp]=x;} 
	inline bool empty() {return !tp;}
	inline int top() {return st[tp];}
}s;

#include<queue>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

priority_queue<int,vector<int>,greater<int> > q;

int n,x,o;

int main(){
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>o;
		if(o==1){
			cin>>x;
			q.push(x);
		}
		else if(o==2){
			cout<<q.top()<<endl;
		}
		else{
			q.pop();
		}
	}
	return 0;
}

ST表

#include<cmath>
#include<cstdio>
#include<algorithm>
#define R register
using namespace std;

inline void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    x*=f;
}

int n,m,a[105050][30];
int x,y; 

inline int query(int x,int y){
    int l=log2(y-x+1);
    return max(a[x][l],a[y-(1<<l)+1][l]); 
}

int main()
{
    read(n);read(m);
    for(R int i=1;i<=n;i++){
    	read(a[i][0]);
    }	
    for(R int j=1;j<=18;j++)
        for(R int i=1;i+(1<<j)-1<=n;i++){
        	a[i][j]=max(a[i][j-1],a[i+(1<<(j-1))][j-1]);
        }
    for(R int i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        print(query(x,y));
        printf("\n");
    }
}

树状数组1

#include<cstdio>
#include<iostream>
#include<algorithm>

using namespace std;

/*----------------HUI----------------*/

int n,m,x,y,z;
int sz[505050];

inline int lowbit(int x){
    return x&(-x);
}

inline void add(int x,int y){
    for(int i=x;i<=n
    ;i+=lowbit(i)){
        sz[i]+=y;
    }
}

inline int sum(int x){
    int ans=0;
    for(int i=x;i>0;i-=lowbit(i)){
        ans+=sz[i];
    }
    return ans;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>x;
        add(i,x);
    }
    while(m--){
        cin>>x;
        if(x==1){
            cin>>y>>z;
            add(y,z);
        }
        else{
            cin>>y>>z;
            cout<<sum(z)-sum(y-1)<<endl;
        }
    }
    return 0;
} 

树状数组2

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long 
int n;
int m;
int ci[500010];
int a,b,c,d;
int ai[500010];
int cf;
int lowbit(int x)
{
    return x&(-x);
}
int getsum(int x)
{
    int ans=0;
    for (int i = x; i > 0; i-= lowbit(i))
    {
        /* code */
        ans+=ci[i];
    }
    return ans;
}
void add(int x,int y)
{
    for (int i = x; i <= n; i+=lowbit(i))
    {
        /* code */
        ci[i]+=y;
    }
}
signed main()
{
    scanf("%lld%lld",&n,&m);
    ai[0]=0;
    for (int i = 1; i <= n; ++i)
    {
        /* code */
        scanf("%lld",&ai[i]);
        cf=ai[i]-ai[i-1];
        add(i,cf);
    }
    while ( m-- )
    {
        scanf("%lld",&a);
        if(a==1)
        {
            scanf("%lld%lld%lld",&b,&c,&d);
            add(b,d);
            add(c+1,-d);
        }
        else if(a==2)
        {
            scanf("%lld",&b);
            printf("%lld\n",getsum(b));
        }
    }
    return 0;
} 

冰茶姬

#include<iostream>
using namespace std;

int n,m;
int x,y,z;
int fa[205050];

int find(int x){
	if(fa[x]==x){
		return x;
	}
	return fa[x]=find(fa[x]);
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		fa[i]=i;
	}
	for(int i=1;i<=m;i++){
		cin>>z>>x>>y;
		if(z==1){
			fa[find(x)]=find(fa[y]);
		}
		else{
			if(find(x)==find(y)){
				cout<<"Y"<<endl;
			}
			else cout<<'N'<<endl;
		}
	}
}

带权冰茶姬

int x,y;
int dis[505050];int siz[505050];
int n;char s;int fa[505050];

inline int find(int x){
    if(x!=fa[x])
    {
        int f=fa[x];
        fa[x]=find(fa[x]);
        dis[x]+=dis[f];
    }
    return fa[x];
}
int main(){
    cin>>n;
    for(int i=1;i<=30000;i++){
    	siz[i]=1;
    	fa[i]=i;
    }
    for(int i=1;i<=n;i++){
    	cin>>s;
    	if(s=='M'){
    		cin>>x>>y;
    		x=find(x),y=find(y);    
            dis[x]=siz[y];
            fa[x]=y;
            siz[y]+=siz[x];
        }
        else{
            cin>>x>>y;
            if(find(x)!=find(y))
                cout<<-1<<endl;
            else
            	cout<<abs(dis[x]-dis[y])-1<<endl;
        }
    }
    return 0;
}

线段树1

#include<cmath> 
#include<cstdio>
#include<iostream>
#include<algorithm>
#define int long long
#define ls o<<1
#define rs o<<1|1
using namespace std;

int n;
int m;
int a[405050];
int tg[405050];
int b,c,d,e,f;

inline void up(int o){
    a[o]=a[ls]+a[rs];
}

inline void build(int o,int l,int r){
    if(l==r){
        cin>>a[o];
        return;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    up(o);
}

inline void down(int o,int l,int r){
    if(tg[o]){
        tg[ls]+=tg[o];
        tg[rs]+=tg[o];
        int mid=(l+r)>>1;
        a[ls]+=(mid-l+1)*tg[o];
        a[rs]+=(r-mid)*tg[o];
        tg[o]=0;
    }
}

inline void change(int o,int l,int r,int x,int y,int z){
    if(x<=l and y>=r)
    {
        a[o]+=(r-l+1)*z;
        tg[o]+=z;
        return;
    }
    down(o,l,r);
    int mid=(l+r)>>1;
    if(x<=mid) change(ls,l,mid,x,y,z);
    if(y>mid)change(rs,mid+1,r,x,y,z);
    up(o);
}

inline int query(int o,int l,int r,int x,int y){
    if(l>=x and r<=y){
        return a[o];		
    }
    down(o,l,r);int res=0;
    int mid=(l+r)>>1;
    if(x<=mid) res+=query(ls,l,mid,x,y);
    if(y>mid) res+=query(rs,mid+1,r,x,y);
    return res;
}

signed main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        cin>>b;
        if(b==1){
            cin>>c>>d>>e;
            change(1,1,n,c,d,e);
        }
        else{
            cin>>c>>d;
            cout<<query(1,1,n,c,d)<<endl;
        }
    }	
    return 0;
}

线段树2

#include<cstdio>
#include<iostream>
using namespace std;
#define II long long
#define mod 100500
#define QWQ ((mod<<2)+5)
#define LS(x) (x<<1)
#define RS(x) ((x<<1)|1)
#define M(x,y) ((x+y)>>1)
#define R register
#define IL inline

II a[mod],st[QWQ],add[QWQ],mul[QWQ];
II n,m,p,flag;

IL void build(II now, II l, II r)
{
    mul[now]=1;
    add[now]=0;
    if(l == r)
    {
        st[now] = a[l];
    }
    else
    {
        R II mid = M(l,r);
        build(LS(now), l, mid);
        build(RS(now), mid+1, r);
        st[now] = st[LS(now)] + st[RS(now)];
    }
    st[now] %= p;
}
IL void push_down(R II now, R II l, R II r)
{
    R II mid = M(l,r);
    st[LS(now)] = (st[LS(now)]*mul[now]+(mid-l+1)*add[now])%p;
    st[RS(now)] = (st[RS(now)]*mul[now]+(r-mid)*add[now])%p;
    mul[LS(now)] = (mul[LS(now)]*mul[now])%p;
    mul[RS(now)] = (mul[RS(now)]*mul[now])%p;
    add[LS(now)] = (add[LS(now)]*mul[now]+add[now])%p;
    add[RS(now)] = (add[RS(now)]*mul[now]+add[now])%p;
    mul[now] = 1;
    add[now] = 0;
    return ;
}
IL void multiply(R II now,R II nowl,R II nowr,R II l,R II r,R II k)
{
    if(nowr < l || nowl > r)
        return ;
    if(nowr <= r && nowl >= l)
    {
        st[now] = (st[now]*k)%p;
        mul[now] = (mul[now]*k)%p;
        add[now] = (add[now]*k)%p;
        return ;
    }
    push_down(now, nowl, nowr);
    R II mid = M(nowl,nowr);
    multiply(LS(now),nowl,mid,l,r,k);
    multiply(RS(now),mid+1,nowr,l,r,k);
    st[now] = ( st[LS(now)] + st[RS(now)] )%p;
    return;
}
IL void jia(R II now,R II nowl,R II nowr,R II l,R II r,R II k)
{
    if(nowr < l || nowl > r)
        return ;
    if(nowr <= r && nowl >= l)
    {
        add[now] = (add[now]+k)%p;
        st[now] = (st[now] + k*(nowr-nowl+1))%p;
        return ;
    }
    push_down(now, nowl, nowr);
    R II mid = M(nowl,nowr);
    jia(LS(now),nowl,mid,l,r,k);
    jia(RS(now),mid+1,nowr,l,r,k);
    st[now] = ( st[LS(now)] + st[RS(now)] )%p;
    return;
}
IL II query(R II now,R II nowl,R II nowr,R II l,R II r)
{
    if(nowl > r || nowr < l)
        return 0;
    if(nowl >= l && nowr <=r)
        return st[now];
    push_down(now,nowl,nowr);
    R II mid = M(nowl,nowr);
    return (query(LS(now),nowl,mid,l,r)+query(RS(now),mid+1,nowr,l,r))%p;
}
int main()
{
    scanf("%lld %lld %lld",&n,&m,&p);
    for (R II i = 1; i <= n; i ++)
    {
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    R II x,y,k;
    while (m--)
    {
        scanf("%lld",&flag);
        if(flag == 1)
        {
            scanf("%lld %lld %lld",&x,&y,&k);
            multiply(1,1,n,x,y,k);
        }
        if(flag == 2)
        {
            scanf("%lld %lld %lld",&x,&y,&k);
            jia(1,1,n,x,y,k);
        }
        if(flag == 3)
        {
            scanf("%lld %lld",&x,&y);
            printf("%lld\n",query(1,1,n,x,y));
        }
    }
    return 0;
}

技巧与思想

对拍

color A
echo off 
:loop
 echo 已运行%a%次
 set /a a+=1
 shuju.exe
 dou.exe
 factory.exe
 fc factory1.out factory2.out
 if not errorlevel 1 goto loop
pause

测运行时间

#include<bits/stdc++.h>
using namespace std;
int main()
{
    for(int i=1;i!=-1;i++)
    {
        system("data.exe");
        int t=clock();
        system("cannon.exe");
        int b=clock();
        cout<<"cannon的第"<<setw(6)<<rand()<<" "<<"次运行时间为: "<<b-t<<"ms"<<endl;
    }
}

二维前缀和

qwq不想写了

快速排序

sort(qwq)

悬线法

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
using namespace std;

int n,m;
int ans1;
int ans2;
int a[2007][2007];
int l[2007][2007],r[2007][2007],u[2007][2007];

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            l[i][j]=j;
            r[i][j]=j;
            u[i][j]=1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=2;j<=m;j++){
            if(a[i][j]!=a[i][j-1]){
                l[i][j]=l[i][j-1];
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=m-1;j>=1;j--){
            if(a[i][j]!=a[i][j+1]){
                r[i][j]=r[i][j+1];
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int lon;
            if(i>1&&a[i][j]!=a[i-1][j]){
                u[i][j]=u[i-1][j]+1;
                r[i][j]=min(r[i-1][j],r[i][j]);
                l[i][j]=max(l[i-1][j],l[i][j]);
            }
            int chang=r[i][j]-l[i][j]+1;
            int shu=min(chang,u[i][j]);
            ans1=max(ans1,shu*shu);
            ans2=max(ans2,chang*u[i][j]);
        }
    }    
    cout<<ans1<<endl<<ans2<<endl;
    return 0;
}

快读qaq

inline void read(int &x){
	int f=1;x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	x*=f; 
}

三分法

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define eps 1e-8

using namespace std;

int n;
double a[105];
double l,r;

inline double f(double x){
	double ans=0;
	for(int i=n;i>=0;i--){
		ans=ans*x+a[i];
	}
	return ans;
}

int main(){
	cin>>n>>l>>r;
	for(int i=n;i>=0;i--){
		cin>>a[i];
	}
	 
	while(fabs(r-l)>=eps){
		double mid=(r-l)/3.0;
		double mid1=l+mid;
		double mid2=r-mid;
		if(f(mid1)<=f(mid2)){
			l=mid1;
		}
		else r=mid2;
	}
	printf("%.5lf",l);
	return 0;
}

最长公共子序列

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000007

using namespace std;

int n;

struct node{
    int a;
    int ord;
    bool operator < (const node &b)const
    {
        return a<b.a;
    }
}a[N];

int b[N],d[N];

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].a);
        a[i].ord=i;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++){
        int k=b[i];
        b[i]=a[k].ord;
    }
    int len=1;
    memset(d,127/3,sizeof(d));
    d[1]=b[1];
    for(int i=1;i<=n;i++){
        if(d[len]<b[i]){
            d[++len]=b[i];
        }
        else {
            int j=lower_bound(d+1,d+len+1,b[i])-d;
            d[j]=b[i];
        }
    }
    cout<<len<<endl;
    return 0;
}

LIS

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define ll long long
#define IL inline
#define R register
using namespace std;
int n;
int a[105050];
int f[105050];
int g[105050];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }    
    int ans=1;
    int ans2=1;
    g[1]=f[1]=a[1];
    for(int i=2;i<=n;i++){
        if(a[i]>f[ans]){
            f[++ans]=a[i];
        }
        else{
            *upper_bound(f+1,f+1+ans,a[i])=a[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

计算几何

最小圆覆盖

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define cq(i,s,n) for(int i=s;i<=n;i++)
using namespace std;
const double eps=1e-12;
struct Point{
    double x,y;
}a[500005];
Point o;
int n; 
double ri;

inline void read(int &x){
    int f=1;x=0;char s=getchar();
    while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
    while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
    x*=f;
}
inline void print(int x){
    if(x<0){
        putchar('-');
        x=-x;
    }
    if(x>9)	print(x/10);
    putchar(x%10+'0');
}

double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 
}

void tt(Point p1,Point p2,Point p3){
    double a,b,c,d,e,f;
    a=p2.y-p1.y;
    b=p3.y-p1.y;
    c=p2.x-p1.x;
    d=p3.x-p1.x;
    f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
    e=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
    o.x=(a*f-b*e)/(2*a*d-2*b*c);
    o.y=(d*e-c*f)/(2*a*d-2*b*c);
    ri=dis(o,p1);
}

int main(){
    scanf("%d",&n);
    cq(i,1,n){
        scanf("%lf%lf",&a[i].x,&a[i].y);
    }
    random_shuffle(a+1,a+n+1);
    o=a[1];ri=0;
    for(int i=2;i<=n;i++){
        if(dis(a[i],o)>ri+eps){
            o=a[i];ri=0;
            for(int j=1;j<=i-1;j++){
                if(dis(o,a[j])>ri+eps){
                    o.x=(a[i].x+a[j].x)/2;
                    o.y=(a[i].y+a[j].y)/2;
                    ri=dis(o,a[j]);
                    for(int k=1;k<=j-1;k++){
                        if(dis(o,a[k])>ri+eps){
                            tt(a[i],a[j],a[k]);
                        }
                    }
                }
            }
        }
    }
    printf("%.10lf\n%.10lf %.10lf",ri,o.x,o.y);
    return 0;
}

二维凸包

#include<iostream>
#include<cstdio>
#include<cmath> 
#include<algorithm>
using namespace std;
struct node{
    double x,y,p;//横纵坐标,极∠。
    node(double x=0,double y=0):x(x),y(y){	}//? 
    friend node operator-(const node&a,const node&b){
    return node(a.x-b.x,a.y-b.y);	
    }
    friend double operator^(const node&a,const node&b){
    return a.x*b.y-a.y*b.x;	
    }
    double mod(){
        return sqrt(x*x+y*y);
    }//封装了三个函数,分别是距离,叉积和??? 
}a[10007];
bool cmp(const node&a,const node&b){
    return a.p<b.p;
}
bool vis[10007];
int s[10007];//手写栈; 
int top;//栈顶;
int minn=1;//最小值 ...定义成一。。。看下面。 
int n;
double ans; 
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&a[i].x,&a[i].y);
        if(a[minn].y>a[i].y||(a[minn].y==a[i].y&&a[minn].x>a[i].x))//左下
        {
        	minn=i;
    	}		 
    }
    swap(a[1],a[minn]);
    for(int i=2;i<=n;i++)
    {
        a[i].x-=a[1].x;
        a[i].y-=a[1].y;
        a[i].p=atan2(a[i].y,a[i].x);//极∠。//cmath自带 
    }
    sort(a+2,a+1+n,cmp);
    a[1].x=0;
    a[1].y=0;
    s[1]=1;
    s[2]=2;
    s[3]=3;
    top=3;
    for(int i=4;i<=n;i++)
    {
    	while(top>2&&((a[s[top]]-a[s[top-1]])^(a[i]-a[s[top]]))<0)
            top--;
        s[++top]=i;
    }
    for(int i=1;i<top;i++)
    {
        ans+=(a[s[i+1]]-a[s[i]]).mod();
    }
    ans+=(a[n]-a[1]).mod();
    printf("%.2lf",ans);
    return 0;
}

字符串

字符串哈希

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio> 
#include<set>
#define mod 100000007
using namespace std;

struct node{
    char a[1600];
    int len;
    int hash(){
        int ans=0;
        for(int i=1;i<=len;i++)
            ans=(ans*10+a[i])%(int)mod;
        return ans;
    }
}b[10007];

int n;
set<int> p;
int ans=0;

int main(){
	cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%s",b[i].a+1);
        b[i].len=strlen(b[i].a+1);
    } 
    for(int i=1;i<=n;i++){
        int ha=b[i].hash();
        if(!p.count(ha)){
            p.insert(ha);
            ans++;
        }
    }
    cout<<ans<<endl;
	return 0;
}


KMP

#include<cmath> 
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

/*----------------HUI----------------*/

inline void read(int &x){
    x=0;int f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 
    x*=f;
}

char s1[1050500],s2[1050500];
int next[1050500],f[1050500];

int main(){
    cin>>(s1+1);
    cin>>(s2+1);
    int m=strlen(s1+1);
    int n=strlen(s2+1);
    next[1]=0;
    for(int i=2,j=0;i<=n;i++){
        while(j>0&&s2[i]!=s2[j+1]) j=next[j];
        if(s2[i]==s2[j+1]) j++;
        next[i]=j;
    }
    for(int i=1,j=0;i<=m;i++){
        while(j>0&&(j==m||s1[i]!=s2[j+1])) j=next[j];
        if(s1[i]==s2[j+1]) j++;
        f[i]=j;
        if(f[i]==n){
            cout<<i-n+1<<endl;
        }
    }
    for(int i=1;i<=n;i++){
        cout<<next[i]<<' ';
    }
    return 0;
}

tire

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
int idx=0;
int tir[500086];
char s[100];
int sum[505050];
bool vis[505050]; 
inline void insert(char *s){
	int rt=0;
	for(int i=0;s[i];i++){
		int v=s[i]-'a';
		if(!tir[rt]){
			tir[rt]=++idx;
		}
		rt=tir[rt];
	}
	sum[rt]++;
	vis[rt]=0;
}

inline int query(char *s){
	int rt=0;
	for(int i=0;s[i];i++){
		int v=s[i]-'a';
		if(!tirrt){
			return 0;
		} 
		rt=tirrt; 
	} 
	if(!sum[rt]){
		return 0;
	}
    else if(vis[rt]==0){
		vis[rt]=1;
		return 1;
	}
	else{
		return 2;
	}

}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s;
		insert(s);
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>s;
		int QAQ=query(s);
		if(QAQ==0){
			cout<<"WRONG"<<endl;
		}
		else if(QAQ==1){
			cout<<"OK"<<endl;
		}
		else{
			cout<<"REPEAT"<<endl;
		}
	}
	return 0;
}

manacher


#include<map>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

/*----------------HUI----------------*/

char s[20505000],str[20505000];
int Len[20505000],len;

inline void getstr(){//处理要用的字符串 
	int k=0;
	str[k++]='$';
	for(int i=0;i<len;i++){
		str[k++]='#';
		str[k++]=s[i];
	}
	str[k++]='#';
	len=k;
}

inline void manacher(){//manacher
	getstr();
	int mx=0,id;
	for(int i=1;i<len;i++){
		if(mx>i){
			Len[i]=min(Len[2*id-i],mx-i);
		}
			else Len[i]=1;
			while(str[i+Len[i]]==str[i-Len[i]]){
				Len[i]++;
			}
			if(Len[i]+i>mx){
				mx=Len[i]+i;
				id=i;
			}
		}
	} 

int main(){
	scanf("%s",&s);
    len=strlen(s);
    manacher();
    int ans=1;
    for(int i=1;i<len;i++) ans=max(ans,Len[i]);
    printf("%d\n",ans-1);
	return 0;
}

高精

struct node{
    int s[10000];
    int len;
    node(){//名字和结构体名字一样(node)
        memset(s,0,sizeof(s));
        len=0;
    }//结构体默认构造函数,新建时自动调用
    void scan()//结构体成员函数,输入
    {
        char c[10000];
        scanf("%s",c);
        int o=strlen(c);
        for(len=0;len<o;len++) 
            s[len]=c[o-len-1]-'0';//从左往右为从低位到高位
    }
    bool operator < (node p) const
    {
        if(len!=p.len) return len<p.len;
        for(int i=len-1;i>=0;i--) 
            if(s[i]!=p.s[i]) return s[i]<p.s[i];
        return 0;
    }
    bool operator == (node p) const
    {
        for(int i=max(len,p.len)-1;i>=0;i--)
            if(s[i]!=p.s[i]) return 0;
        return 1;
    }
    bool operator > (node p) const
    {
        if(len!=p.len) return len>p.len;
        for(int i=len-1;i>=0;i--) 
            if(s[i]!=p.s[i]) return s[i]>p.s[i];
        return 0;
    }
    node operator + (node a){//高精加高精
        node c;
        c.len=max(len,a.len);
        for(int i=0;i<c.len;i++)
        {
            c.s[i]+=s[i]+a.s[i];
            if(c.s[i]>9) c.s[i]-=10,c.s[i+1]++;
        }
        if(c.s[c.len]) c.len++;
        return c;
    }
    node operator - (node a){//高精减高精
        if(*this<a)
            printf("-"),swap(*this,a);
        for(int i=0;i<len;i++){
            s[i]-=a.s[i];
            while(s[i]<0) s[i]+=10,s[i+1]-=1;
        }
        if(!s[len-1]) len--;
        while(!s[len-1])len--;
        return *this;
    }
    node operator / (int a){//高精除低精
        int x=0;//余数
        node c;
        c.len=len;
        for(int i=len-1;i>=0;i--)
        {
            c.s[i]=(s[i]+x*10)/a;
            x=s[i]%a;
        }
        if(!c.s[len-1]) c.len--;
        return c;
    }
    node operator * (node a){//高精乘高精
        node c;
        for(int i=0;i<len;i++)
            for(int j=0;j<a.len;j++){
                c.s[i+j]+=s[i]*a.s[j];
                if(c.s[i+j]>9) c.s[i+j+1]+=c.s[i+j]/10,c.s[i+j]%=10;
            }
        c.len=len+a.len;
        if(!c.s[c.len-1]) c.len--;
        return c;
    }
    node operator + (int a){//高精加低精
        s[0]+=a;
        int i=0;
        while(s[i]>9) s[i]-=10,s[i+1]++,i++;
        if(s[len]) len++;
        return *this;//返回调用这个函数的自己
    }
    node operator - (int a){//高精减低精 
        s[0]-=a;
        int i=0;
        while(s[i]<0) s[i]+=10,s[i+1]--,i++;
        if(!s[len-1]) len--;
        return *this;//返回调用这个函数的自己
    }
    int operator % (int a){//高精度取模低精度
        int re=0;
        for(int i=0;i<len;i++)
            re=(re*10+s[i])%a;
        return re;
    }
};
posted @ 2018-10-04 17:21  enceladus  阅读(...)  评论(...编辑  收藏

Contact with me