zoukankan      html  css  js  c++  java
  • 板子们(不定时更新)

    板子们

    早期写代码大括号竟然换行,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
    ");
    	for(int i=2;i<=n;i++){
    		inv[i]=(p-p/i)*inv[p%i]%p;
    		printf("%lld
    ",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
    ",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
    ");
                continue;
            }
            node ans=multiply(chu,ksm(e,n-3));
            printf("%lld
    ",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?'
    ':' ');
                }
        }
    }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
    ",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
    ",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
    ",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
    ",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("
    ");
        }
    }
    

    树状数组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
    ",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
    ",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
    %.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
    ",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;
        }
    };
    
  • 相关阅读:
    把csv文件导入数据库
    c# DataTable 针对xml、excel、csv导入和导出
    ASP.NET常用珍藏代码
    C# 判断图片链接是否存在
    在asp.net中长内容自动分页的实现.NET教程
    SQL代理服务启动不了SQLSERVERAGENT
    SQL重复记录查询(转载)
    在asp.net中长内容自动分页的实现.NET教程2
    根据年月来判断月里天数
    SQL字符串函数
  • 原文地址:https://www.cnblogs.com/enceladus-return0/p/9742642.html
Copyright © 2011-2022 走看看