正题
题目连接:https://www.luogu.com.cn/problem/P7887?contestId=52021
题目大意
给出三个长度为nnn的序列xi,yi,zix_i,y_i,z_ixi,yi,zi,求一个序列aaa满足0≤ai<109+70\leq a_i<10^9+70≤ai<109+7且
xi(∑j=1iaj)+yi(∑j=inaj)≡zi(mod109+7)x_i\left(\sum_{j=1}^ia_j\right)+y_i\left(\sum_{j=i}^na_j\right)\equiv z_i(mod\ 10^9+7)xi(j=1∑iaj)+yi(j=i∑naj)≡zi(mod 109+7)
如果只有一组解就输出这组解
1≤∑n≤2×105,1≤xi,yi<109+7,0≤zi<109+71\leq \sum n\leq 2\times 10^5,1\leq x_i,y_i<10^9+7,0\leq z_i<10^9+71≤∑n≤2×105,1≤xi,yi<109+7,0≤zi<109+7
解题思路
看到这个同余就感觉这题是个啥方程的做法类的
设si=∑j=1iajs_i=\sum_{j=1}^ia_jsi=∑j=1iaj那么有
xisi+yi(sn−si−1)=zix_is_i+y_i(s_n-s_{i-1})=z_ixisi+yi(sn−si−1)=zi
这样我们就有了si,si−1,sns_i,s_{i-1},s_nsi,si−1,sn之间的关系式,而对于s1s_1s1我们可以直接得到它和sns_nsn的关系式
x1s1+y1sn=z1⇒s1=z1−y1snx1x_1s_1+y_1s_n=z_1\Rightarrow s_1=\frac{z_1-y_1s_n}{x_1}x1s1+y1sn=z1⇒s1=x1z1−y1sn
这样我们可以设si=Ai+Bisns_i=A_i+B_is_nsi=Ai+Bisn,然后用上面的式子化为
si=zi+yisi−1−yisnxis_i=\frac{z_i+y_is_{i-1}-y_is_n}{x_i}si=xizi+yisi−1−yisn
推出后面的A,BA,BA,B,最后有
sn=An+Bnsn⇒sn=An1−Bns_n=A_n+B_ns_n\Rightarrow s_n=\frac{A_n}{1-B_n}sn=An+Bnsn⇒sn=1−BnAn
当然Bn=1B_n=1Bn=1时需要判断AnA_nAn是否为000来得到解数。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e5+10,P=1e9+7;
ll T,n,x[N],y[N],z[N],a[N],b[N],s[N];
ll power(ll x,ll b){ll ans=1;x%=P;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
};
signed main()
{scanf("%lld",&T);while(T--){scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld%lld%lld",&x[i],&y[i],&z[i]);ll inv=power(x[1],P-2);a[1]=z[1]*inv%P;b[1]=(P-y[1])*inv%P;for(ll i=2;i<=n;i++){inv=power(x[i],P-2);a[i]=(a[i-1]*y[i]%P+z[i])*inv%P;b[i]=(b[i-1]*y[i]%P-y[i]+P)%P*inv%P;}if(b[n]==1){printf("%lld\n",a[n]?0:P);continue;}s[n]=a[n]*power((1-b[n]+P)%P,P-2)%P;for(ll i=1;i<n;i++)s[i]=(a[i]+b[i]*s[n]%P)%P;puts("1");for(ll i=1;i<=n;i++)printf("%lld ",(s[i]-s[i-1]+P)%P);putchar('\n');} return 0;
}