codeforce#420 E. Okabe and El Psy Kongroo(图论+矩阵快速幂)

来源:互联网 发布:淘宝军刺暗语 编辑:程序博客网 时间:2024/06/05 00:07

题目链接

E. Okabe and El Psy Kongroo

分析

首先对于坐标为 (x,y) 的点,设 f(x,y) 表示从原点到 (x,y) 的路径不难得到递推公式 f(x,y)=f(x1,y1)+f(x1,y)+f(x1,y+1),很明显这和把每个点建图然后能达点建边构造的图是一样的,显然计算复杂度太高,观察表达式,我们发现 x 并没有什么作用,因为只能向前走 (x>x+1),因此我们可以只对 y 坐标建图,建立邻接矩阵,对于点 (i,j) 如果可以从y=i>y=j则设d[i][j]=1 矩阵dk[i][j]y=iky=j 那么只需对每一条线段都建立这样的矩阵,然后计算 dbiai再把所有矩阵相乘就是答案.

AC code

#include<bits/stdc++.h>#define pb push_back#define mp make_pair#define fi first#define se second#define INF 0x3f3f3f3f#define ALL(x) (x.begin(),x.end())#define ms(x,v) memset(x,v,sizeof(x))using namespace std;typedef long long LL;typedef pair<LL,LL> Pair;typedef pair<int,pair<int,int> > Point;const int maxn = 3e5+10;const LL MOD = 1e9+7;const int sz = 16;struct matrix{   LL m[sz][sz];   matrix(){      ms(m,0);   }   void init(int y){      ms(m,0);      for(int i=1 ; i<y ; ++i){         m[i][i+1]=m[i][i-1] = m[i][i] =1;      }      if(y)m[0][1]=m[0][0] = m[y][y]=m[y][y-1] =1;      else m[0][0] =1;   }   void init(){      for(int i=0 ; i<sz ; ++i)m[i][i] =1;   }   void print(){      for(int i=0 ;i<sz ; ++i)      {         for(int j=0 ; j<sz ; ++j)            std::cout << m[i][j] << ' ';         std::cout  << '\n';      }   }};matrix mul(matrix& A,matrix & B){   matrix ret;   for(int i=0 ; i<sz ; ++i){      for(int j=0 ; j<sz ; ++j){         ret.m[i][j] = 0;         for(int k=0 ; k<sz ; ++k)            ret.m[i][j] += A.m[i][k] * B.m[k][j],ret.m[i][j]%=MOD;      }   }   return ret;}matrix power_mod(matrix x,LL n){   matrix ret;   ret.init();   while (n) {      //std::cout << "n = " <<n << '\n';      if(n&1)ret = mul(ret,x);      x = mul(x,x);      //ret.print();      n>>=1;   }   return ret;}matrix A[2];int main(){  ios::sync_with_stdio(false);  cin.tie(0);  LL n,k;  cin>>n>>k;  int t=0;  ms(A,0);  A[t].init();  for(LL i=0  ; i<n ;++i){     LL a,b,y;     cin>>a>>b>>y;     if(i == n-1)b=k;     t ^=1;     A[t].init(y);     A[t] = power_mod(A[t],b-a);     A[t] = mul(A[t^1],A[t]); }   std::cout << A[t].m[0][0] << '\n';  return 0;  }

参考

editorial

阅读全文
0 0