zoukankan      html  css  js  c++  java
  • Noip蒟蒻专用模板

    模板

    数论

    线性筛素数

    #include <bits/stdc++.h>
    using namespace std;
    int n,notp[20000000],pri[2000000],tot;
    void get(){
    	notp[1]=1;
    	for(int i=2;i<=n;i++){
    		if(!notp[i]) pri[++tot]=i;
    		for(int j=1;j<=tot&&i*pri[j]<=n;j++){
    			notp[i*pri[j]]=1;
    			if(i%pri[j]==0) break;
    		}
    	}
    }
    int k;
    int main(){
    	scanf("%d%d",&n,&k);
    	get();
    	for(int i=1;i<=k;i++){
    		int a;
    		scanf("%d",&a);
    		if(!notp[a])puts("Yes");
    		else puts("No");
    	}
    }
    

    线性筛欧拉

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    int notp[500000],pri[500000],cnt,phi[500000],n;
    void get(){
    	notp[1]=1;
    	for(int i=2;i<=n;i++){
    		if(!notp[i]) pri[++cnt]=i,phi[i]=i-1;
    		for(int j=1;j<=cnt && i*pri[j]<=n;j++){
    			notp[i*pri[j]]=1;
    			if(i%pri[j]!=0)phi[i*pri[j]]=phi[i]*(pri[j]-1);
    			if(i%pri[j]==0){
    				phi[i*pri[j]]=phi[i]*pri[j];
    				break;
    			}
    		}
    	}
    }
    int main(){
    	scanf("%d",&n);
    	get();
    	for(int i=1;i<=n;i++)printf("%d ",phi[i]);
    }
    

    裴蜀定理

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    int gcd(int x,int y)
    {
        return !y ? x : gcd(y,x%y);
    }
    int a , ans;
    int main()
    {
        cin >> n;
        cin >> ans;
        if(ans <0 )ans = -ans;
        for(int i = 2;i <= n;i ++)
        {
            cin >> a;
            if(a <0 )
                a = -a;
            ans = gcd(ans , a);
        }
        cout << ans;
    }
    

    卢卡斯定理

    #include <cstdio>
    using namespace std;
    typedef long long LL;
    int n,m,p;
    LL inv[200011],fac[200101];
    void get() {
        inv[1]=1;
        fac[0]=1;
        inv[0]=1;
        for(int i=1; i<=m+n; i++)fac[i]=fac[i-1]*i%p;
        for(int i=2; i<=m+n; i++)inv[i]=(p-p/i)%p*inv[p%i]%p;
        for(int i=2; i<=m+n; i++)inv[i]=inv[i-1]*inv[i]%p;
    }
    LL lucas(int x,int y) {
        if(x<y) return 0;
        else if(x<p) return fac[x]*inv[y]%p*inv[x-y]%p;
        else return lucas(x/p,y/p)%p*lucas(x%p,y%p)%p;
    }
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d%d%d",&n,&m,&p);
            get();
            printf("%lld
    ",lucas(n+m,m)%p);
        }
    }
    

    矩阵快速幂

    #include<iostream>
    #include<cstring>
    #define LL long long
    using namespace std;
    const int  mod = 1000000007;
    LL n,k;
    struct edge
    {
        LL a[101][101];
    };
    edge A,B;
    edge multi(edge x,edge y)
    {
        edge C;
        memset(C.a,0,sizeof(C.a));
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j++)
                for(int k = 1; k <= n; k ++)
                    C.a[i][j]+=(x.a[i][k]*y.a[k][j])%mod,C.a[i][j]%=mod;
        return C;
    }
    int main()
    {
        cin >> n >> k;
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= n; j ++)
                cin >> A.a[i][j];
        for(int i = 1; i <= n; i ++)
            B.a[i][i]=1;
        while(k)
        {
            if(k&1)B=multi(B,A);
            A=multi(A,A);
            k>>=1;
        }
        for(int i = 1; i <= n; i ++)
        {
            for(int j = 1; j <= n; j ++)
                cout << B.a[i][j] << ' ';
            cout << endl;
        }
    }
    

    逆元

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    long long A[5000000];
    int n,p;
    int main() {
        A[1]=1;
        cin >> n >> p;
        for(int i=2; i<=n; i++) {
            A[i]=((p-p/i)*A[p%i]%p+p)%p;
        }
        for(int i=1; i<=n; i++)printf("%d
    ",A[i]);
    }
    

    高斯消元

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #define eps 1e-10
    using namespace std;
    double a[200][200];
    int n;
    void guass() {
        for(int i=1; i<=n; i++) {
            int wz=0;
            for(int j=i; j<=n; j++)
                if(fabs(a[j][i])>eps) {
                    wz=j;
                    break;
                }
            if(wz==0) {
                puts("No Solution");
                exit(0);
            }
            if(wz!=i)swap(a[i],a[wz]);
            double tmp=a[i][i];
            for(int j=1; j<=n+1; j++)a[i][j]/=tmp;
            for(int j=i+1; j<=n; j++) {
                double tmp=a[j][i];
                for(int k=1; k<=n+1; k++)a[j][k]-=a[i][k]*tmp;
            }
        }
        for(int i=n; i>=1; i--)
            for(int j=i+1; j<=n; j++) 
                if(fabs(a[i][j])>eps)
                    a[i][n+1]-=a[j][n+1]*a[i][j],a[i][j]=0;
    }
    int main() {
    //	freopen("a.in","r",stdin);
        cin >> n;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n+1; j++)
                cin >> a[i][j];
        guass();
        for(int i=1; i<=n; i++)printf("%.2lf
    ",a[i][n+1]);
    }
    

    图论

    割点

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N = 20010,M = 200010;
    struct edge {
    	int next,to;
    } e[M];
    int head[N],tot;
    void add(int x,int y) {
    	e[++tot].next = head[x];
    	head[x] = tot;
    	e[tot].to = y;
    }
    int n,m,low[N],dfn[N],cnt,vis[N];
    void tarjan(int x,int f) {
    	int num=0;
    	dfn[x]=++cnt;
    	low[x]=cnt;
    	for(int i=head[x]; i; i=e[i].next) {
    		int v=e[i].to;
    		if(v == f)continue;
    		if(!dfn[v]) {
    			num++;
    			tarjan(v,x);
    			low[x]=min(low[x],low[v]);
    			if(f!=0 && low[x]>=dfn[x]) vis[x]=1;
    		} else low[x]=min(low[x],dfn[v]);
    	}
    	if(f==0 && num>=2) vis[x]=1;
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for(int i=1; i<=m; i++) {
    		int a,b;
    		scanf("%d%d",&a,&b);
    		add(a,b),add(b,a);
    	}
    	int ans=0;
    	for(int i=1; i<=n; i++)
    		if(!dfn[i])tarjan(i,0);
    	for(int i=1;i<=n;i++) if(vis[i]) ans++;
    	printf("%d
    ",ans);
    	for(int i=1; i<=n; i++) if(vis[i]) printf("%d
    ",i);
    }
    

    最小生成树

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define N 5001
    using namespace std;
    int n,m;
    int a,b,c,ans;
    int flag[N],map[N][N],dis[N];
    int main()
    {
        memset(map,0x3f,sizeof(map));
        memset(dis,0x3f,sizeof(dis));
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>a>>b>>c;
            map[a][b]=min(map[a][b],c);
            map[b][a]=map[a][b];
        }
        dis[1]=0;
        int k;
        for(int i=1;i<=n;i++)
        {
            k=0;
            for(int j=1;j<=n;j++)
                if(!flag[j]&&dis[j]<dis[k])
                    k=j;
            flag[k]=1;
            for(int j=1;j<=n;j++)
                if(!flag[j]&&map[k][j]<dis[j])
                    dis[j]=map[k][j];
        }
        for(int i=1;i<=n;i++)
        {
            if(!flag[i])
            {
                cout<<"orz";
                return 0;
            }
            ans+=dis[i];
        }
        cout<<ans;
    }
    

    倍增

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const int N = 500100;
    struct edge {
        int next,to;
    } e[N<<1];
    int head[N],tot;
    void add(int x,int y) {
        e[++tot].next=head[x];
        head[x]=tot;
        e[tot].to=y;
    }
    int n,m,rt;
    int f[N][32],deep[N];
    void dfs(int x,int fa) {
        f[x][0]=fa;
        deep[x]=deep[fa]+1;
        for(int i=1; i<=21; i++)f[x][i]=f[f[x][i-1]][i-1];
        for(int i=head[x]; i; i=e[i].next) {
            int v=e[i].to;
            if(v == fa) continue;
            dfs(v,x);
        }
    }
    int LCA(int x,int y) {
        if(deep[x]<deep[y]) swap(x,y);
        int delta=deep[x]-deep[y];
        for(int i=21; i>=0; i--) 
            if(delta >= (1<<i)) {
                delta-=(1<<i);
                x=f[x][i];
            }
        for(int i=21;i>=0;i--){
            if(f[x][i]!=f[y][i]){
                x=f[x][i];
                y=f[y][i];
            }
        }
        if(x!=y) x=f[x][0];
        return x;
    }
    int main() {
        scanf("%d%d%d",&n,&m,&rt);
        for(int i=1; i<=n-1; i++) {
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        deep[rt]=1;
        dfs(rt,0);
        while(m--){
            int a,b;
            scanf("%d%d",&a,&b);
            printf("%d
    ",LCA(a,b));
        }
    }
    

    SPFA

    #include<bits/stdc++.h>
    using namespace std;
    queue<int>q;
    struct edge
    {
        int next,to,dist;
    } e[500007];
    int head[500007],tot;
    inline void add(int x,int y,int z)
    {
        e[++tot].next=head[x];
        e[tot].to=y;
        e[tot].dist=z;
        head[x]=tot;
    }
    int n,m,s;
    int f,g,w;
    long  vis[500007],dis[500010];
    void spfa()
    {
        while(!q.empty())q.pop();
        for(int i=1; i<=n; i++)dis[i]=2147483647;
        dis[s]=0;
        q.push(s);
        vis[s]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u],v; v=e[i].to,i; i=e[i].next)
                if(e[i].dist+dis[u]<dis[v])
                {
                    dis[v]=dis[u]+e[i].dist;
                    if(!vis[v])
                        vis[v]=1,q.push(v);
                }
        }
    }
    int main()
    {
        cin>>n>>m>>s;
        for(int i=1; i<=m; i++)cin>>f>>g>>w,add(f,g,w);
        spfa();
        for(int i=1;i<=n;i++)cout<<dis[i]<<' ';
        return 0;
    }
    

    负环

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define N 20000
    using namespace std;
    struct edge {
    	int next , to , dist;
    } e[N];
    int head[N] , tot , vis[N] , dis[N] , T , n , m , num[N];
    inline void add(int x,int y,int z) {
    	e[++tot].next = head[x];
    	e[tot].to = y;
    	e[tot].dist = z;
    	head[x] = tot;
    }
    bool spfa(int s) {
    	memset(dis,0x3f3f,sizeof(dis));
    	queue<int>q;
    	vis[s] = 1;
    	q.push(s);
    	num[s]++;
    	dis[s]=0;
    	while(!q.empty()) {
    		int u = q.front();
    		q.pop();
    		vis[u] = 0;
    		for(int i = head[u],v; i,v=e[i].to; i=e[i].next)
    			if(dis[v]>dis[u]+e[i].dist) {
    				num[v]++;
    				if(num[v]>=n)return true;
    				dis[v] = dis[u]+e[i].dist;
    				if(!vis[v])
    					vis[v] = 1,q.push(v);
    			}
    	}
    	return false;
    }
    int main() {
    	cin >> T;
    	while(T--) {
    		scanf("%d%d",&n,&m);
    		memset(vis,0,sizeof(vis));
    		memset(num,0,sizeof(num));
    		memset(head,0,sizeof(head));
    		tot = 0;
    		for(int i = 1; i <= m; i ++) {
    			int a , b , w;
    			scanf("%d%d%d",&a,&b,&w);
    			if(w>=0) {
    				e[++tot].next = head[a];
    				e[tot].to = b;
    				e[tot].dist = w;
    				head[a] = tot;
    				e[++tot].next = head[b];
    				e[tot].to = a;
    				e[tot].dist = w;
    				head[b] = tot;
    			} else {
    				e[++tot].next = head[a]
    				                ;
    				e[tot].to = b;
    				e[tot].dist = w;
    				head[a] = tot;
    			}
    		}
    		if(spfa(1))
    			printf("YE5
    ");
    		else printf("N0
    ");
    	}
    }
    

    堆优化迪杰斯特拉

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    using namespace std;
    typedef long long LL;
    const int N = 100010,M = 200020;
    struct edge {
    	int next,to,dis;
    } e[M];
    struct node {
    	int id,dis;
    	node() {}
    	node(int a,int b) {
    		id=a,dis=b;
    	}
    };
    priority_queue<node>q;
    bool operator <(const node &a,const node &b) {
    	return a.dis>b.dis;
    }
    int n,m,st,dis[N],head[N],tot;
    void add(int x,int y,int z) {
    	e[++tot].next = head[x];
    	head[x] = tot;
    	e[tot].to = y;
    	e[tot].dis = z;
    }
    void dijkstra(int s) {
    	memset(dis,0x3f,sizeof(dis));
    	dis[s]=0;
    	q.push(node(s,0));
    	while(!q.empty()) {
    		node x=q.top();
    		q.pop();
    		int u=x.id,d=x.dis;
    		if(dis[u]!=d) continue;
    		for(int i=head[u]; i; i=e[i].next) {
    			int v=e[i].to;
    			if(dis[v]>dis[u]+e[i].dis) {
    				dis[v]=dis[u]+e[i].dis;
    				q.push(node(v,dis[v]));
    			}
    		}
    	}
    }
    int main() {
    	scanf("%d%d%d",&n,&m,&st);
    	for(int i=1; i<=m; i++) {
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		add(a,b,c);
    	}
    	dijkstra(st);
    	for(int i=1; i<=n; i++)printf("%d ",dis[i]);
    }
    

    匈牙利

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    const int N = 2000;
    int n,m,M;
    int _map[N][N],result[N],vis[N];
    bool dfs(int u) {
    	for(int v=1; v<=m; v++)
    		if(!vis[v]&&_map[u][v]) {
    			vis[v]=1;
    			if(!result[v]||dfs(result[v])) {
    				result[v]=u;
    				return true;
    			}
    		}
    	return false;
    }
    int solve() {
    	int ans=0;
    	for(int u=1; u<=n; u++) {
    		memset(vis,0,sizeof(vis));
    		if(dfs(u))ans++;
    	}
    	return ans;
    }
    int main() {
    	scanf("%d%d%d",&n,&m,&M);
    	for(int i=1; i<=M; i++) {
    		int a,b;
    		scanf("%d%d",&a,&b);
    		_map[a][b]=1;
    	}
    	printf("%d
    ",solve());
    }
    

    数据结构

    树状数组

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 500001;
    int tree[N],n,m;
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x,int y)
    {
        while(x<=n)
        {
            tree[x]+=y;
            x+=lowbit(x);
        }
    }
    int sum(int x)
    {
        int ans=0;
        while(x!=0)
        {
            ans+=tree[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            int a;
            scanf("%d",&a);
            add(i,a);
        }
        for(int i=1; i<=m; i++)
        {
            int opt,x,y;
            scanf("%d%d%d",&opt,&x,&y);
            if(opt==1)add(x,y);
            else if(opt==2)printf("%d
    ",sum(y)-sum(x-1));
        }
    }
    

    ST表

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,ST[100010][30];
    void work(){
    	for(int j=1;j<=21;j++){
    		for(int i=1;i+(1<<j)-1<=n;i++)
    			ST[i][j]=max(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
    	}
    }
    int find(int l,int r){
    	int k=log2(r-l+1);
    	return max(ST[l][k],ST[r-(1<<k)+1][k]);
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%d",&ST[i][0]);
    	work();
    	for(int i=1;i<=m;i++){
    		int a,b;
    		scanf("%d%d",&a,&b);
    		printf("%d
    ",find(a,b));
    	}
    }
    

    线段树

    #include<bits/stdc++.h>
    using namespace std;
    long long n,p,a,b,m,x,y,ans;
    struct node {
    	long long l,r,w,f;
    } tree[500000];
    inline void build(int k,int ll,int rr) {
    	tree[k].l=ll,tree[k].r=rr;
    	if(tree[k].l==tree[k].r) {
    		cin>>tree[k].w;
    		return;
    	}
    	int m=(ll+rr)/2;
    	build(k<<1,ll,m);
    	build(k<<1|1,m+1,rr);
    	tree[k].w=tree[k<<1].w+tree[k<<1|1].w;
    }
    inline void down(int k) {
    	tree[k<<1].f+=tree[k].f;
    	tree[k<<1|1].f+=tree[k].f;
    	tree[k<<1].w+=tree[k].f*(tree[k<<1].r-tree[k<<1].l+1);
    	tree[k<<1|1].w+=tree[k].f*(tree[k<<1|1].r-tree[k<<1|1].l+1);
    	tree[k].f=0;
    }
    inline void ask_interval(int k) {
    	if(tree[k].l>=a&&tree[k].r<=b) {
    		ans+=tree[k].w;
    		return;
    	}
    	if(tree[k].f) down(k);
    	int m=(tree[k].l+tree[k].r)/2;
    	if(a<=m) ask_interval(k<<1);
    	if(b>m) ask_interval(k<<1|1);
    }
    inline void change_interval(int k) {
    	if(tree[k].l>=a&&tree[k].r<=b) {
    		tree[k].w+=(tree[k].r-tree[k].l+1)*y;
    		tree[k].f+=y;
    		return;
    	}
    	if(tree[k].f) down(k);
    	int m=(tree[k].l+tree[k].r)/2;
    	if(a<=m) change_interval(k<<1);
    	if(b>m) change_interval(k<<1|1);
    	tree[k].w=tree[k<<1].w+tree[k<<1|1].w;
    }
    int main() {
    	cin>>n>>m;
    	build(1,1,n);
    	for(int i=1; i<=m; i++) {
    		cin>>p;
    		ans=0;
    		if(p==1) {
    			cin>>a>>b>>y;
    			change_interval(1);
    		}
    		if(p==2) {
    			cin>>a>>b;
    			ask_interval(1);
    			cout<<ans<<endl;
    		}
    	}
    }
    

    字符串

    kmp

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    char s1[2000000],s2[2000000];
    int kmp[2000000];
    int main() {
    	cin >> s1 >> s2;
    	int len1=strlen(s1);
    	int len2=strlen(s2);
    	int k=0;
    	for(int i=1; i<len2; i++) {
    		while(k&&s2[k]!=s2[i])k=kmp[k];
    		kmp[i+1]=(s2[k]==s2[i])?++k:0;
    	}
    	k=0;
    	for(int i=0; i<len1; i++) {
    		while(k&&s1[i]!=s2[k])k=kmp[k];
    		(s1[i]==s2[k])?++k:0;
    		if(k==len2) printf("%d
    ",i+1-k+1);
    	}
    	for(int i=1; i<=len2; i++)printf("%d ",kmp[i]);
    }
    

    DP

    最长公共子序列

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    int n,a[200000],b[200000];
    int dp[2000][2000];
    int main()
    {
        cin>>n;
        for(int i=1; i<=n; i++)
            cin>>a[i];
        for(int i=1; i<=n; i++)
            cin>>b[i];
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                if(a[i]==b[j])
                    dp[i][j]=max(dp[i][j],dp[i-1][j-1])+1;
            }
        cout<<dp[n][n];
    }
    
  • 相关阅读:
    compass 制作css sprites
    net模块
    javascript -- 代理模式
    javascript -- 单例模式
    js 对象的浅拷贝和深拷贝
    js 对象的封装,继承,多态的理解
    this,call,apply
    flex 实现圣杯布局
    ubuntu中安装mongodb
    devDependencies和dependencies的区别
  • 原文地址:https://www.cnblogs.com/ifmyt/p/9909218.html
Copyright © 2011-2022 走看看