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;
}