2019牛客暑期多校訓練營(第二場) E MAZE

2022-08-21 18:39:13 字數 1624 閱讀 5400

題意:n×m的矩陣,0表示可以走,1表示牆,不能通過。有q中操作,一種是改變座標(x,y)的狀態,一種是詢問從(1,x)到(n,y)有多少條路徑。(n,q<=5e4,m<=10)。

思路:dp、矩陣乘加線段樹維護。

dp[i][j]表示從第i行到(i,j)的路徑數。則dp[i][j]=sum(dp[i][k](k<=j)) + sum(dp[i][k](k>j))。

比如上圖,dp[1][2]=dp[1][1]+dp[1][2]+dp[1][3]。

dp[1][6]=dp[1][5]+dp[1][6]。

因此第x行到第y行的路徑數可以用轉移矩陣表示,比如從第1行到第1行的轉移矩陣為:

其中第1行第3列的1表示從(1,1)到(1,3)有1條路經。

用線段樹維護矩陣的乘積,修改為單點修改,複雜度為o(m^3*logn),樹根維護的是m1*...*mn,即第1行到第n行的路徑數,所以查詢複雜度為o(1)。

ac**:

#include#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxn=50005

;const

int mod=1e9+7

;struct

mat;

struct

nodetr[maxn

<<2

];int

n,m,q;

char s[12

];int a[maxn][12

];mat matmul(mat& a,mat&b)

}returnc;}

void matupd(int v,intx)}

void pushup(int

v)void build(int v,int l,int

r)

int mid=(l+r)>>1

; build(v

<<1

,l,mid);

build(v

<<1|1,mid+1

,r);

pushup(v);

}void update(int v,int

x)

int mid=(tr[v].l+tr[v].r)>>1

;

if(x<=mid) update(v<<1

,x);

else update(v<<1|1

,x);

pushup(v);

}int

main()

build(

1,1,n);

while(q--)

else

printf(

"%lld\n

",tr[1

].m.mat[x][y]);

}return0;

}

2019牛客暑期多校訓練營(第二場)

題意 題解 c 版本一 include using namespace std typedef long long ll const int mod 1e9 7 ll power ll a,ll b a是底數,b是次冪 return ans ll phi ll n 求尤拉函式值 返回值為多少個與n互...

2019牛客暑期多校訓練營(第二場)

有2 n個人,平均分為兩隊,當i和j不在同一隊時,獲得權值vij v vi j 求權值總和的最大值 暴力!暴力!暴力!首先劃分28個人有c 2814 c c2 814 種情況,約為4e7,然後計算權值總和本來需要14 14的複雜度,這樣肯定會t,因此需要想辦法優化這個14 14,於是我在翻別人的 的...

E MAZE 2019牛客暑期多校訓練營(第二場)

給出n行m列的迷宮0可走1不可走,有兩個操作,操作1變換點 a,b 的值,操作2查詢 1,a 到 n,b 的方案數 設 f i j 為第i 1行到達第i行第j列的方案數,若點 i,j 上下為0的可延伸範圍為 l,r 則 f i j sum r f i 1 k 由這個式子就可以構造出第i 1行到第i行...