題意: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行...