• 组合计数3以及高斯消元


    组合计数

    卡特兰数满足的性质:

    1.递减式:f(n)=f(1)*f(n-1)+f(2)*f(n-2)+....

    2.挖掘性质:任意前缀中的某种东西>=另一种东西

    3.直觉看到3的答案是5可能是卡特兰数

    1. 有趣的数列

    信息学奥赛一本通(C++版)在线评测系统

    这题就是卡特兰数

    这题就是要满足:奇数项的个数大于偶数项的个数,我们可以把奇数项看成0,偶数项看成1

    然后有1~2n个位置,奇数项对应0,偶数项对应1,相当于给我们n个0,n个1,然后保证任意前缀里面0的个数要大于等于1的个数,所以这题就对应了上一节的一道题了

    然后这题答案就是C(2n,n)-C(2n,n-1),然后用分解质因式+快速幂来求mod数,因为mod数会变所以不能用逆元来求C(a,b)=a!/(b!*(a-b)!)

    1. #include
    2. using namespace std;
    3. typedef long long ll;
    4. const int N=2e6+10;
    5. int primes[N],cnt;
    6. bool st[N];
    7. int n,p;
    8. void init(int n)//筛质数
    9. {
    10. for(int i=2;i<=n;i++)
    11. {
    12. if(!st[i]) primes[cnt++]=i;
    13. for(int j=0;primes[j]*i<=n;j++)
    14. {
    15. st[primes[j]*i]=true;
    16. if(i%primes[j]==0) break;
    17. }
    18. }
    19. }
    20. int qmi(int a,int k)//快速幂
    21. {
    22. int res=1;
    23. while(k)
    24. {
    25. if(k&1) res=(ll)res*a%p;
    26. a=(ll)a*a%p;
    27. k>>=1;
    28. }
    29. return res;
    30. }
    31. int get(int n,int p)//获取一个阶层的p次方s
    32. {
    33. int s=0;
    34. while(n) s+=n/p,n/=p;
    35. return s;
    36. }
    37. int C(int a,int b)//获取C(a,b)
    38. {
    39. int res=1;
    40. for(int i=0;i//分解质因式的方式求
    41. {
    42. int prime=primes[i];
    43. int s=get(a,prime)-get(b,prime)-get(a-b,prime);
    44. res=(ll)res*qmi(prime,s)%p;//乘以p的s次方
    45. }
    46. return res;
    47. }
    48. int main()
    49. {
    50. cin>>n>>p;
    51. init(2*n);
    52. cout<<(C(2*n,n)-C(2*n,n-1)+p)%p<//输出卡特兰数
    53. return 0;
    54. }

    高斯消元

    1.球形空间产生器

    207. 球形空间产生器 - AcWing题库

    直接求得的方程为

    再进行转换就可以得到线性方程

    1. #include
    2. using namespace std;
    3. const int N=15;
    4. double a[N][N],b[N][N];
    5. int n;
    6. void gauss()
    7. {
    8. //转化成上三角矩阵
    9. for(int r=1,c=1;c<=n;c++,r++)
    10. {
    11. //找主元
    12. int t=r;
    13. for(int i=r+1;i<=n;i++)
    14. if(fabs(b[i][c]>fabs(b[t][c])))
    15. t=i;
    16. //交换
    17. for(int i=c;i<=n+1;i++) swap(b[t][i],b[r][i]);
    18. //归一化
    19. for(int i=n+1;i>=c;i--) b[r][i]/=b[r][c];
    20. //消当前列的当前行的下面行的数为0
    21. for(int i=r+1;i<=n;i++)
    22. for(int j=n+1;j>=c;j--)
    23. b[i][j]-=b[i][c]*b[r][j];
    24. }
    25. //转化成对角矩阵
    26. for(int i=n;i>1;i--)
    27. for(int j=i-1;j;j--)
    28. {
    29. b[j][n+1]-=b[i][n+1]*b[j][i];
    30. b[j][i]=0;
    31. }
    32. }
    33. int main()
    34. {
    35. scanf("%d",&n);
    36. for(int i=0;i<=n;i++)
    37. for(int j=1;j<=n;j++)
    38. scanf("%lf",&a[i][j]);
    39. for(int i=1;i<=n;i++)//转化成线性方程
    40. for(int j=1;j<=n;j++)
    41. {
    42. b[i][j]=2*(a[i][j]-a[0][j]);
    43. b[i][n+1]+=a[i][j]*a[i][j]-a[0][j]*a[0][j];
    44. }
    45. gauss();//高斯消元
    46. for(int i=1;i<=n;i++) printf("%.3lf ",b[i][n+1]);//输出答案
    47. return 0;
    48. }

    2.开关问题

    208. 开关问题 - AcWing题库

    线性方程组等式右边应该是灯最后的状态 不是1 2 3

     方案数取决于我们自由元的个数,每个自由元有两种情况0或者1,则假如自由元有k个则,答案有2^k个方案,k就是n - 非0行的个数也即自由元

    1. #include
    2. using namespace std;
    3. const int N=35;
    4. int n;
    5. int a[N][N];
    6. int gauss()
    7. {
    8. int r,c;
    9. for(r=1,c=1;c<=n;c++)
    10. {
    11. //找主元
    12. int t=r;
    13. for(int i=r+1;i<=n;i++)
    14. if(a[i][c])
    15. t=i;
    16. //假如最大已经是了,则这一列不用操作了
    17. if(!a[t][c]) continue;
    18. //交换
    19. for(int i=c;i<=n+1;i++) swap(a[t][i],a[r][i]);
    20. //消
    21. for(int i=r+1;i<=n;i++)
    22. for(int j=n+1;j>=c;j--)
    23. a[i][j]^=a[i][c]&a[r][j];
    24. r++;
    25. }
    26. int res=1;
    27. if(r1)//求自由元个数
    28. {
    29. for(int i=r;i<=n;i++)
    30. {
    31. if(a[i][n+1]) return -1;//出现了0==!0无解
    32. res*=2;//每个自由元都有两个状态则就是*2
    33. }
    34. }
    35. return res;
    36. }
    37. int main()
    38. {
    39. int T;
    40. scanf("%d",&T);
    41. while(T--)
    42. {
    43. memset(a,0,sizeof a);//清空
    44. scanf("%d",&n);
    45. for(int i=1;i<=n;i++) scanf("%d",&a[i][n+1]);//存初始状态
    46. for(int i=1;i<=n;i++)
    47. {
    48. int t;
    49. scanf("%d",&t);
    50. a[i][n+1]^=t;//初始跟末状态异或
    51. a[i][i]=1;//自己这盏灯影响自己的状态
    52. }
    53. int x,y;
    54. while(scanf("%d%d",&x,&y),x||y) a[y][x]=1;//x影响y这盏灯则y这行x会影响他
    55. int t=gauss();
    56. if(t==-1) puts("Oh,it's impossible~!!");//假如无解
    57. else printf("%d\n",t);
    58. }
    59. return 0;
    60. }

  • 相关阅读:
    Mongo的数据操作
    AIDL 如何分片传输大量 Parcelable 数据列表
    ChatGPT,AIGC 制作按年份选择的动态条形图
    一文带你看透手机号码归属地
    Tomcat:servlet与servlet容器
    基于VUE + Echarts 实现可视化数据大屏智慧校园可视化
    自定义类似微信效果Preference
    Oracle/PLSQL: NANVL Function
    代码报错:There‘s no Qt version assigned to project Project.vcxproj
    文本文件的读取+操作
  • 原文地址:https://blog.csdn.net/lee_14141/article/details/127748547