#loj3093 [BJOI2019]光线
Posted sweetphoenix
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#loj3093 [BJOI2019]光线相关的知识,希望对你有一定的参考价值。
一开始推合并两个镜子的做法
然后自闭了
于是开始写消元,发现矩阵很有特点稍微优化下就行了
可以将每个镜子拆成正面和反面两个点,然后连边建高斯消元的图
将点以特定的方式重新编号之后发现可以从矩阵的左上角开始进行代入消元法
那剩下的事情就好说了,使用map存储整个矩阵就可以了
\(O(nlogn)\)
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;typedef long long ll;const ll mod=1e9+7;
const int N=1e6+10;
inline ll po(ll a,ll p){ll r=1;for(;p;p>>=1,a=a*a%mod)if(p&1)r=r*a%mod;return r;}
//ll mp[N][N];
map <int,ll> mp[N];
bool book[N];ll cval[N];
inline void solve(int row)
{
ll sum=0;int ns=-1;ll xs=0;
for(map <int,ll> :: iterator it=mp[row].begin();it!=mp[row].end();++it)
if(book[it->first])(sum+=(mod-it->second)*cval[it->first])%=mod;
else ns=it->first,xs=po(it->second,mod-2);
// printf("solve %d,ns=%d\n",row,ns);
cval[ns]=sum*xs%mod;book[ns]=true;
}
int n;int S;
/*inline void prit()
{
for(int i=1;i<=S;i++)
{
for(int j=1;j<=S+1;j++)
printf("%lld ",mp[i].count(j));printf("\n");
}
printf("\n");
}*/
/*inline void gauss()
{
prit();
for(int i=1;i<=S;i++)
{
// prit();
if(mp[i][i]==0)
{
for(int j=i+1;j<=S;j++)
if(mp[j][i]!=0)
{
for(int k=i;k<=S+1;k++)swap(mp[i][k],mp[j][k]);
break;
}
}
ll iv=po(mp[i][i],mod-2);
for(int k=i;k<=S+1;k++)
(mp[i][k]*=iv)%=mod;
for(int j=1;j<=S;j++)
if(j!=i)
{
for(int k=S+1;k>=i;k--)
(mp[j][k]+=(mod-mp[j][i])*mp[i][k])%=mod;
}
}
}*/
ll fa[N];ll fb[N];
inline void push(int u,int v,ll val)
{
// printf("add %d %d\n",u,v);
(mp[u][v]+=mod-val)%=mod;
}
int main()
{
ll iv100=po(100,mod-2);
scanf("%d",&n);
S=2*n;
for(int i=1;i<=n;i++)
scanf("%lld%lld",&fa[i],&fb[i])
,(fa[i]*=iv100)%=mod,
(fb[i]*=iv100)%=mod;
for(int i=1;i<n;i++)
push(i<<1,(i+1)<<1,fa[i]);
for(int i=n;i>=2;i--)
push(i<<1|1,(i-1)<<1|1,fa[i]);
for(int i=2;i<=n;i++)
push(i<<1,(i-1)<<1|1,fb[i]);
for(int i=1;i<n;i++)
push(i<<1|1,(i+1)<<1,fb[i]);
for(int i=1;i<=2*n;i++)
mp[i][i]=1;
//prit();
//(mp[n<<1][S+1]+=fa[n])%=mod;
//gauss();
cval[2]=1;book[2]=true;
for(int i=2;i<(n<<1);i++)
solve(i);
ll sum=0;
for(map <int,ll >:: iterator it=mp[n<<1].begin();it!=mp[n<<1].end();++it)
(sum+=it->second*cval[it->first])%=mod;
printf("%lld",fa[n]*po(sum,mod-2)%mod);
return 0;
}
以上是关于#loj3093 [BJOI2019]光线的主要内容,如果未能解决你的问题,请参考以下文章