5.19 模拟赛

5.19 模拟赛

数学专题

A Triangle

题意:给定一个圆上的n个点,每两个点之间有一条权值为1或0的边,求三条边权值相同的三角形个数

解:用总三角形数减去异色三角形的个数,具体做法是枚举每个点所连的边里权值为0和1的边数,用总数减去乘积,因为每个边算了两次所以要除以2,即答案是

\[ans=C_n^3-\frac{\sum_{i=1}^n s[i][0]*s[i][1]}{2} \]

\(s[i][0/1]\)表示与第i个点相连的边里权值为0/1的边数

码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<deque>
#include<set>
#include<stack>
#include<bitset>
#include<cstring>
#define ll long long
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
using namespace std;
const int INF=0x3f3f3f3f,N=1000010,Mod=1e9+7;

inline ll read(){
    ll x=0,y=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') y=-1;c=getchar();}
    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*y;
}

ll t,n,ans=0;
int mapp[1010][1010];
int s[1010][2];

int main(){
	
	// freopen("triangle.in","r",stdin);
	// freopen("triangle.out","w",stdout);
	
	t=read();
	
	while(t--){
		memset(s,0,sizeof s);
		ans=0;
		n=read();
		for(int i=1;i<=n-1;i++) for(int j=i+1;j<=n;j++){
			int k;
			scanf("%d",&k);
			s[i][k]++;
            s[j][k]++;
		}
		
		for(int i=1;i<=n;i++){
			ans+=s[i][1]*s[i][0]/2;
		}
		
		ans=(n*(n-1)*(n-2)/6)-ans;
					
		printf("%d\n",ans);
	}
	
	// fclose(stdin);
	// fclose(stdout);
	
    return 0;
}

B 和果子

题意:和果子,一种日式点心,以糖,糯米,小豆等为主要原料。将小豆煮沸去皮后制成豆馅,混入甜砂糖。豆馅通常用年糕包住,制成各式各样的精美点心。特色和果子如“善哉(ZENZAI)”,将小豆和年糕加入粘稠甜味的汤制成; “落雁”是将砂糖压入木雕模型而制成,里面没有小豆;羊羹也是特色之一。给出n组数,组内数不重复,组内数为小于等于n的正整数,求选择哪几组数能够使得1到n每个数都选择了奇数次,数据保证有且只有一个解

解:高斯消元解异或方程组

对每一个含有a的组异或起来答案为1

解方程组

码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<deque>
#include<set>
#include<stack>
#include<bitset>
#include<cstring>
#define ll long long
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
using namespace std;
const int INF=0x3f3f3f3f,N=260;
double eps=1e-8;

namespace gauss_jordan{
    struct anss{
        int s[N];
        string st;
    };

    anss gauss_jordan(int n,int a[N][N]){
        anss ans;
        ans.st="Yes";
        bool vis[N];
        int tmpmax;
        int maxr;
        for(int i=1;i<=n;i++){
            tmpmax=0;
            maxr=i;
            for(int j=1;j<=n;j++){
                if(!vis[j]&&a[j][i]==1){
                    tmpmax=a[j][i];
                    maxr=j;
                    break;
                }
            }
            if(maxr!=i) swap(a[i],a[maxr]);
            vis[i]=true;
            for(int j=1;j<=n;j++){
                if(i!=j){
                    if(a[j][i]==0) continue; 
                    for(int k=1;k<=n+1;k++) a[j][k]^=a[i][k];
                }
            }

        }

        for(int i=1;i<=n;i++){
            ans.s[i]=a[i][n+1];
        }

        return ans;
    }
}

int mapp[N][N],h[N],gs[N][N];

int main(){

    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int k;
        scanf("%d",&k);
        while(k!=-1){
            mapp[i][++h[i]]=k;
            scanf("%d",&k);
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=h[i];j++){
            gs[mapp[i][j]][i]=1;
        }
    }

    for(int i=1;i<=n;i++){
        gs[i][n+1]=1;
    }

    gauss_jordan::anss a=gauss_jordan::gauss_jordan(n,gs);

    for(int i=1;i<=n;i++){
        if(a.s[i]==1) printf("%d ",i); 
    }
    

    return 0;
}

C 矩阵的幂

题意:求矩阵幂和(不带\(A^0\))

wangk的神奇评测机帮我把100卡到了40,好耶

gyx讲的幂和板子题

\[powsum(n)=\begin{cases} (I+A^{\frac{n}{2}})*powsum(\frac{n}{2})&n\%2=0\\ A\times powsum(n-1)&n\%2=1 \end{cases} \]

码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<deque>
#include<set>
#include<stack>
#include<bitset>
#include<cstring>
#define ll long long
#define max(a,b) ((a>b)?a:b)
#define min(a,b) ((a<b)?a:b)
using namespace std;
const int INF=0x3f3f3f3f,N=50;

inline ll read(){
    ll x=0,y=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') y=-1;c=getchar();}
    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    return x*y;
}

int Mod,n,m;

struct Matrix{
	int m,n;
	int a[N][N];
	
	inline void init(int _m=0,int _n=0){
		m=_m;n=_n;
		memset(a,0,sizeof a);
	}
    
    inline Matrix operator + (Matrix B){
		Matrix res;
        res.init(m,n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                res.a[i][j]=a[i][j]+B.a[i][j];
        return res;
    }
    
    inline Matrix operator - (Matrix B){
		Matrix res;
        res.init(m,n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                res.a[i][j]=(a[i][j]-B.a[i][j]+Mod)%Mod;
        return res;
    }
    
    inline Matrix operator * (int c){
		Matrix res;
        res.init(m,n);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                res.a[i][j]=c*a[i][j];
        return res;
    }
	
	inline Matrix operator * (Matrix B){
		Matrix res;
		res.init(m,B.n);
		for(int i=1;i<=m;i++)
			for(int j=1;j<=B.n;j++)
				for(int k=1;k<=n;k++)
					(res.a[i][j]+=a[i][k]*B.a[k][j])%=Mod;
		return res;
	}
	
	inline void id(){
		for(int i=1;i<=n;i++) a[i][i]=1;
	}
	
	inline Matrix fpow(int t){
		Matrix res;
		res.init(m,m);
		res.id();
		Matrix tmp=*this;
		for(;t;t>>=1,tmp=tmp*tmp) if(t&1) res=res*tmp;
		return res;
	}

}matr,ans,idd;

inline Matrix powsum(Matrix A,int k){
    Matrix I;
    I.init(A.m,A.m);
    I.id();
    if(k==0) return I;
    Matrix op;
    if(k&1) op=I+A*(powsum(A,k-1));
    else op=I+(I+A.fpow(k/2))*(A*powsum(A,k/2-1));
    return op;
}

int main(){
	
	// freopen("Matrix.in","r",stdin);
	// freopen("Matrix.out","w",stdout);
	
	scanf("%d%d%d",&n,&m,&Mod);
	
	matr.init(n,n);
	idd.init(n,n);
	idd.id();
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&matr.a[i][j]);
	
	ans=powsum(matr,m);
	ans=ans-idd;
	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			printf("%d ",ans.a[i][j]%Mod);
		}
		printf("\n");
	}
	
	// fclose(stdin);
	// fclose(stdout);
	
    return 0;
}
posted @ 2021-05-20 22:10  wsy_jim  阅读(56)  评论(0编辑  收藏  举报