zoukankan      html  css  js  c++  java
  • 【洛谷7016】[CERC2013] Captain Obvious and the Rabbit-Man(手动高斯消元)

    点此看题面

    • (p_i=sum_{j=1}^na_jFib_j^i),给定(n)(p_{1sim n}),求(p_{n+1})
    • (nle4 imes10^3)

    手动高斯消元

    发现这道题中有(n)个未知数(a_{1sim n}),然后(p_{1sim n})就相当于是(n)个方程,因此容易想到高斯消元,但(O(n^3))的一般高斯消元显然无法通过此题。

    要是真想把这(n)个未知数全部解出来肯定没有优化的余地,因此下面先来一步转化:

    我们在最后添上(p_{n+1})这个方程(等号右边的值先定为(0))和前面的方程一起消元,发现在前(n)个方程消元结束后(p_{n+1})的所有未知数都被消干净了,因此等号右边值的相反数就是(p_{n+1})了。

    接下来就可以开始优化高斯消元了。

    考虑我们要消去第(i)行之后所有行第(i)列的值,一般的做法是枚举第(i)行从之后的每一行中消去。这样一来后面的列都被减得乱七八糟了,毫无规律可言,完全没有用到系数的性质。

    因此我们要换一种消元的思路:第(i)次消元的时候从后往前枚举每一行,减去上一行( imes Fib_i)

    注意到这里我们相当于根据系数给这个方程组进行了一个手动高斯消元,因此不用再管系数的修改,而只需考虑等号右边值之间的运算,复杂度就是(O(n^2))的了。

    代码:(O(n^2))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 4000
    using namespace std;
    int n,X,a[N+5],Fib[N+5];
    int main()
    {
    	RI Tt,i,j;scanf("%d",&Tt);W(Tt--)
    	{
    		for(scanf("%d%d",&n,&X),i=1;i<=n;++i) scanf("%d",a+i),Fib[i]=i<=2?i:(Fib[i-2]+Fib[i-1])%X;//预处理斐波那契数
    		for(a[n+1]=0,i=1;i<=n;++i) for(j=n+1;j^i;--j) a[j]=(a[j]-1LL*a[j-1]*Fib[i]%X+X)%X;//手动高斯消元
    		printf("%d
    ",(X-a[n+1])%X);//第n+1个方程等号右边值的相反数
    	}return 0;
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    使用iconv编程进行字符集转换
    Unity3D学习之路 C#学习笔记(一)
    跨平台的游戏客户端Socket封装
    TCP长连接与短连接的区别
    C++中的long long和__int64类型
    基于cocos2dx的游戏客户端优化
    Android NDK带来什么
    strcpy_s与strcpy的比较
    英文字母和中文汉字在不同字符集编码下的字节数
    socket的read和recv函数的区别
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu7016.html
Copyright © 2011-2022 走看看