A[HDU2604]求不含子串010和000的,长为\(n\)的01序列数。

B[HDU6470]数列\(\{a_n\}:a_1=1,a_2=2,a_n=a_{n-1}+2a_{n-2}+n^3\),给定\(n\),求\(a_n\)。

C[HDU3306]数列\(\{a_n\}:a_0=a_1=1,a_n=xa_{n-1}+ya_{n-2}\),给定\(n,x,y\),求前\(n\)项平方和。

D[HDU2276]01环,每轮操作改变所有1左边位置的值,求\(m\)轮后的结果。

E[LibreOJ#6208]给定一棵树,点有两个权\(k,t\),支持对某个点到根的路径修改\(k+d \to k\),\(t+k\times d \to t\),询问单点的\(t\)。

F[LibreOJ#2980]给定三个数列\(a,b,c\),支持以下操作:\(a_i+b_i \to a_i\),\(b_i+c_i \to b_i\),\(c_i+a_i \to c_i\),\(a_i+v \to a_i\),\(b_i \times v \to b_i\),\(v \to c_i\),询问\(a,b,c\)的区间和。

G[CF750E]给定数字串,对某个子串,求其至少删去多少个字符,才能使剩余串含子序列2017,但不含子序列2016。

H[洛谷P6573]给定有向图,边有权,边\((x,y)\)满足\(\left\lfloor\dfrac{y}{k}\right\rfloor=1+\left\lfloor\dfrac{x}{k}\right\rfloor\),\(1\le k \le 5\)。求从\(u\)到\(v\)的最小路程。多组询问。

I[洛谷P7359]给定树,每条边有距离\(a\),水流影响\(b\)以及水流向。通过一条边,走路耗时\(a\),顺流而下耗时\(a-b\),逆流而上耗时\(a+b\)。每次上船需要时间\(l\)。求从\(u\)到\(v\)的最小时间。多组询问。

J[洛谷P4719]一棵树,点有权,单点修改,求最大权独立集。

K[洛谷P6021]一棵树,点有权,单点修改,求在某棵子树中选出一些点,使得所有叶子与根不连通的最小权值和。

L[洛谷P5024]一棵树,点有权,给定某两个点的选择状况,求最小权覆盖集。


A维护\(6\times6\)的矩阵,代表可能的\(6\)种结尾三个数。然后用矩阵快速幂。

B移项,求出一个三次函数\(f\)使\(a_n+f(n)=(a_{n-1}+f(n-1))+2(a_{n-2}+f(n-2))\),然后用矩阵快速幂求\(a_n+f(n)\)。

C维护\(a_{n-1}^2,a_{n-2}^2,a_{n-1}a_{n-2},s_{n-1}\),矩阵快速幂。

D看做模2的加法,矩阵快速幂。

E用矩阵刻画修改,先做树链剖分,然后用线段树维护。

F和E类似,但不用树剖。

G先推暴力DP,状态定义为考虑到某个位置,已经匹配到201的第几个位置。然后从后往前找第一个7,它后面的6全部要删去,它前面要留下201。推完发现转移可以用矩阵刻画,然后就用线段树维护。

H每\(k\)个构建一个矩阵。

I矩阵维护在船上和不在船上两个状态,通过一条边的转移可以用矩阵刻画。倍增即可。

动态DP:(通常在树上)用矩阵刻画DP转移。做树链剖分,然后对每个点记录轻儿子的转移矩阵之积。修改时从一个点向上跳,修改每条轻边的贡献;询问是把1所在重链的矩阵相乘。

JKL都是模板。L要注意撤销修改时的顺序。


点击查看A题代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct Matrix{
int a[6][6];
Matrix (){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<6;i++)
for(int j=0;j<6;j++)
for(int k=0;k<6;k++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j]%m)%m;
return c;
}
}t;
Matrix power(Matrix a,int b,Matrix c){
for(;b;b>>=1){if(b&1)c=c*a;a=a*a;}
return c;
}
int main(){
//0ffm 1fmm 2mff 3mfm 4mmf 5mmm
t.a[0][1]=1;t.a[1][4]=1;t.a[1][5]=1;t.a[2][0]=1;
t.a[3][1]=1;t.a[4][2]=1;t.a[4][3]=1;t.a[5][4]=1;t.a[5][5]=1;
while(scanf("%d%d",&n,&m)!=EOF){
if(n<=3){
if(n==0)printf("%d\n",1%m);
if(n==1)printf("%d\n",2%m);
if(n==2)printf("%d\n",4%m);
if(n==3)printf("%d\n",6%m);
continue;
}
Matrix c;
c.a[0][0]=c.a[0][1]=c.a[0][2]=c.a[0][3]=c.a[0][4]=c.a[0][5]=1;
c=power(t,n-3,c);
printf("%d\n",(c.a[0][0]+c.a[0][1]+c.a[0][2]+
c.a[0][3]+c.a[0][4]+c.a[0][5])%m);
}
return 0;
}
点击查看B题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=123456789,inv8=46296296;
int T;ll n;
struct Matrix{
int a[2][2];
Matrix (){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j]%mod)%mod;
return c;
}
}t;
Matrix power(Matrix a,ll b,Matrix c){
for(;b;b>>=1){if(b&1)c=c*a;a=a*a;}
return c;
}
int main(){
t.a[0][0]=0;t.a[0][1]=2;t.a[1][0]=t.a[1][1]=1;
scanf("%d",&T);
while(T--){
scanf("%lld",&n);
Matrix c;c.a[0][0]=277;c.a[0][1]=499;
c=power(t,n-2,c);n%=mod;
ll ans=(c.a[0][1]-(4*n%mod*n%mod*n%mod+30*n%mod*n%mod+96*n%mod+139)%mod
+mod)%mod*inv8%mod;
printf("%lld\n",ans);
}
return 0;
}
点击查看C题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=10007;
struct Matrix{
ll a[4][4];
Matrix (){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
return c;
}
};
Matrix power(Matrix a,ll b,Matrix c){
for(;b;b>>=1){if(b&1)c=c*a;a=a*a;}
return c;
}
ll n,x,y;
int main(){
while(scanf("%lld%lld%lld",&n,&x,&y)!=EOF){
Matrix a,b;
a.a[2][0]=1;a.a[2][1]=x%mod;a.a[1][1]=y%mod;
a.a[0][3]=a.a[0][2]=y*y%mod;
a.a[1][3]=a.a[1][2]=2*x%mod*y%mod;
a.a[2][3]=a.a[2][2]=x*x%mod;a.a[3][3]=1;
b.a[0][0]=b.a[0][1]=b.a[0][2]=1;b.a[0][3]=2;
b=power(a,n-1,b);
printf("%lld\n",b.a[0][3]);
}
return 0;
}
点击查看D题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105,mod=2;
int n,m;char s[N];
struct Matrix{
ll a[N][N];
Matrix (){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
return c;
}
};
Matrix power(Matrix a,ll b,Matrix c){
for(;b;b>>=1){if(b&1)c=c*a;a=a*a;}
return c;
}
int main(){
while(scanf("%d",&m)!=EOF){
scanf("%s",s);n=strlen(s);
Matrix a,b;
for(int i=0;i<n;i++){
a.a[0][i]=s[i]-'0';
b.a[i][i]=b.a[i][(i+1)%n]=1;
}
a=power(b,m,a);
for(int i=0;i<n;i++)printf("%d",a.a[0][i]);
printf("\n");
}
return 0;
}
点击查看E题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m;
int head[N],nxt[N<<1],ver[N<<1],tot;
void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
struct Matrix{
ll a[3][3];
Matrix (int op=1){memset(a,0,sizeof(a));if(op)a[0][0]=a[1][1]=a[2][2]=1;}
Matrix operator *(const Matrix&b)const{
Matrix c(0);
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c.a[i][j]+=a[i][k]*b.a[k][j];
return c;
}
}f,zero;
int fa[N],son[N],top[N],L[N],dfn,siz[N];
void dfs(int u){
siz[u]=1;
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]){
fa[v]=u;dfs(v);siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void rdfs(int u,int tp){
L[u]=++dfn;top[u]=tp;
if(son[u])rdfs(son[u],tp);
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]&&v!=son[u])rdfs(v,v);
}
struct SegmentTree{
Matrix a[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void push_down(int p){
a[ls]=a[ls]*a[p];a[rs]=a[rs]*a[p];
a[p]=zero;
}
void modify(int p,int l,int r,int L,int R,Matrix v){
if(l>=L&&r<=R){a[p]=a[p]*v;return;}
push_down(p);
if(L<=mid)modify(ls,l,mid,L,R,v);
if(R>mid)modify(rs,mid+1,r,L,R,v);
}
Matrix query(int p,int l,int r,int x){
if(l==r)return a[p];
push_down(p);
if(x<=mid)return query(ls,l,mid,x);
else return query(rs,mid+1,r,x);
}
#undef ls
#undef rs
#undef mid
}seg;
void update(int u,Matrix v){
while(u){
seg.modify(1,1,n,L[top[u]],L[u],v);
u=fa[top[u]];
}
}
int main(){
scanf("%d",&n);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1);rdfs(1,1);
scanf("%d",&m);
for(int i=1,op,u,v;i<=m;i++){
scanf("%d%d",&op,&u);
if(op<=2){
scanf("%d",&v);
if(op==1)f.a[2][0]=v,f.a[0][1]=0;
else f.a[0][1]=v,f.a[2][0]=0;
update(u,f);
}
else{
Matrix ans(0);ans.a[0][2]=1;
ans=ans*seg.query(1,1,n,L[u]);
printf("%lld\n",ans.a[0][1]);
}
}
return 0;
}
点击查看F题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2.5e5+5,mod=998244353;
int n,m;
struct Matrix{
ll a[4][4];
Matrix (int op=1){
memset(a,0,sizeof(a));
if(op)a[0][0]=a[1][1]=a[2][2]=a[3][3]=1;
}
Matrix operator +(const Matrix&b)const{
Matrix c(0);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
c.a[i][j]=(a[i][j]+b.a[i][j])%mod;
return c;
}
Matrix operator *(const Matrix&b)const{
Matrix c(0);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
return c;
}
}g[N],zero;
struct SegmentTree{
Matrix sum[N<<2],tag[N<<2];
void init(){
for(int i=1;i<=n*4;i++){Matrix x(0);sum[i]=x;}
}
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void push_up(int p){sum[p]=sum[ls]+sum[rs];}
void push_down(int p){
sum[ls]=sum[ls]*tag[p];sum[rs]=sum[rs]*tag[p];
tag[ls]=tag[ls]*tag[p];tag[rs]=tag[rs]*tag[p];
tag[p]=zero;
}
void build(int p,int l,int r){
if(l==r){sum[p]=g[l];return;}
build(ls,l,mid);build(rs,mid+1,r);
push_up(p);
}
void modify(int p,int l,int r,int L,int R,Matrix v){
if(l>=L&&r<=R){
sum[p]=sum[p]*v;tag[p]=tag[p]*v;
return;
}
push_down(p);
if(L<=mid)modify(ls,l,mid,L,R,v);
if(R>mid)modify(rs,mid+1,r,L,R,v);
push_up(p);
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return sum[p];
push_down(p);
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)+query(rs,mid+1,r,L,R);
}
#undef ls
#undef rs
#undef mid
}seg;
int main(){
scanf("%d",&n);
for(int i=1,a,b,c;i<=n;i++){
scanf("%d%d%d",&a,&b,&c);
Matrix x(0);x.a[0][0]=a;x.a[0][1]=b;x.a[0][2]=c;x.a[0][3]=1;
g[i]=x;
}
seg.init();seg.build(1,1,n);
scanf("%d",&m);
for(int i=1,op,l,r,v;i<=m;i++){
scanf("%d%d%d",&op,&l,&r);
Matrix f;
if(op==7){
f=seg.query(1,1,n,l,r);
printf("%lld %lld %lld\n",f.a[0][0],f.a[0][1],f.a[0][2]);
}
else{
if(op<=3)f.a[op%3][op-1]=1;
else{
scanf("%d",&v);
if(op==4)f.a[3][0]=v;
if(op==5)f.a[1][1]=v;
if(op==6)f.a[2][2]=0,f.a[3][2]=v;
}
seg.modify(1,1,n,l,r,f);
}
}
return 0;
}
点击查看G题代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,INF=1e9+7;
int n,m,cnt[N],lst[N];char s[N];
struct Matrix{
int a[4][4];
Matrix (){memset(a,0x3f,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
}
}g[N];
struct SegmentTree{
Matrix a[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){a[p]=g[l];return;}
build(ls,l,mid);build(rs,mid+1,r);
a[p]=a[ls]*a[rs];
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return a[p];
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)*query(rs,mid+1,r,L,R);
}
#undef ls
#undef rs
#undef mid
}seg;
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s+1);
for(int i=1;i<=n;i++){
g[i].a[0][0]=g[i].a[1][1]=g[i].a[2][2]=g[i].a[3][3]=0;
cnt[i]=cnt[i-1];lst[i]=lst[i-1];
switch(s[i]){
case '2':g[i].a[0][0]=1;g[i].a[0][1]=0;break;
case '0':g[i].a[1][1]=1;g[i].a[1][2]=0;break;
case '1':g[i].a[2][2]=1;g[i].a[2][3]=0;break;
case '6':g[i].a[3][3]=1;++cnt[i];break;
case '7':lst[i]=i;break;
}
}
seg.build(1,1,n);
for(int i=1,l,r;i<=m;i++){
scanf("%d%d",&l,&r);
if(lst[r]<l){
printf("-1\n");
continue;
}
Matrix f;f.a[0][0]=0;
f=f*seg.query(1,1,n,l,lst[r]);
int ans=f.a[0][3]+cnt[r]-cnt[lst[r]];
printf("%d\n",ans>1e9?-1:ans);
}
return 0;
}
点击查看H题代码
#include<bits/stdc++.h>
using namespace std;
const int N=6e4+5;
int k,n,m,q;
struct Matrix{
int a[5][5];
Matrix (){memset(a,0x3f,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
for(int k=0;k<5;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
}
}g[N];
struct SegmentTree{
Matrix a[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){a[p]=g[l];return;}
build(ls,l,mid);build(rs,mid+1,r);
a[p]=a[ls]*a[rs];
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return a[p];
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)*query(rs,mid+1,r,L,R);
}
#undef ls
#undef rs
#undef mid
}seg;
int main(){
scanf("%d%d%d%d",&k,&n,&m,&q);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
g[u/k+1].a[u%k][v%k]=w;
}
seg.build(1,1,n/k);
for(int i=1,u,v;i<=q;i++){
scanf("%d%d",&u,&v);
if(v/k<=u/k){printf("-1\n");continue;}
Matrix f;f.a[0][u%k]=0;
f=f*seg.query(1,1,n/k,u/k+1,v/k);
int ans=f.a[0][v%k];
printf("%d\n",ans>1e9?-1:ans);
}
return 0;
}
点击查看I题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
struct Matrix{
ll a[2][2];
Matrix (){memset(a,0x3f,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
}
};
int n,m,k,fa[N][20],dep[N];Matrix f[N][20],g[N][20];
int head[N],ver[N<<1],nxt[N<<1],tot=1;Matrix val[N<<1];
void add(int u,int v,Matrix w){
ver[++tot]=v;val[tot]=w;
nxt[tot]=head[u];head[u]=tot;
}
void dfs(int u){
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u][0]){
fa[v][0]=u;
f[v][0]=val[i^1];g[v][0]=val[i];
dep[v]=dep[u]+1;
dfs(v);
}
}
void pre(){
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)if(fa[i][j-1]){
fa[i][j]=fa[fa[i][j-1]][j-1];
f[i][j]=f[i][j-1]*f[fa[i][j-1]][j-1];
g[i][j]=g[fa[i][j-1]][j-1]*g[i][j-1];
}
}
int LCA(int u,int v){
if(dep[u]<dep[v])swap(u,v);
int d=dep[u]-dep[v];
for(int i=18;i>=0;i--)
if(d&(1<<i))u=fa[u][i];
if(u==v)return u;
for(int i=18;i>=0;i--)
if(fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][0];
}
int st[50][2],top;
int main(){
scanf("%d%d%d",&n,&k,&m);
for(int i=1,u,v,a,b,t;i<n;i++){
scanf("%d%d%d%d%d",&u,&v,&a,&b,&t);
Matrix w;t=2*t-1;
w.a[0][0]=w.a[1][0]=a;
w.a[0][1]=k+a+t*b;w.a[1][1]=a+t*b;add(v,u,w);
w.a[0][1]=k+a-t*b;w.a[1][1]=a-t*b;add(u,v,w);
}
dfs(1);pre();
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
int t=dep[LCA(u,v)];
Matrix ans;ans.a[0][0]=0;
int s=dep[u]-t;
for(int j=18;j>=0;j--)
if(s&(1<<j))ans=ans*f[u][j],u=fa[u][j];
s=dep[v]-t;top=0;
for(int j=18;j>=0;j--)
if(s&(1<<j))st[++top][0]=v,st[top][1]=j,v=fa[v][j];
while(top)ans=ans*g[st[top][0]][st[top][1]],--top;
printf("%lld\n",min(ans.a[0][0],ans.a[0][1]));
}
return 0;
}
点击查看J题代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,INF=1e9;
int n,m,a[N],f[N][2];
int head[N],nxt[N<<1],ver[N<<1],tot;
void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
int fa[N],top[N],L[N],dfn,R[N],siz[N],son[N],id[N];
struct Matrix{
int a[2][2];
Matrix (){memset(a,0,sizeof(a));}
Matrix operator *(const Matrix &b)const{
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=max(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
}
}g[N];
struct SegmentTree{
Matrix a[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){a[p]=g[id[l]];return;}
build(ls,l,mid);
build(rs,mid+1,r);
a[p]=a[ls]*a[rs];
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return a[p];
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)*query(rs,mid+1,r,L,R);
}
void modify(int p,int l,int r,int x){
if(l==r){a[p]=g[id[l]];return;}
if(x<=mid)modify(ls,l,mid,x);
else modify(rs,mid+1,r,x);
a[p]=a[ls]*a[rs];
}
#undef ls
#undef rs
#undef mid
}seg;
void dfs(int u){
f[u][1]=a[u];siz[u]=1;
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]){
fa[v]=u;
dfs(v);siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
f[u][0]+=max(f[v][0],f[v][1]);
f[u][1]+=f[v][0];
}
}
void rdfs(int u,int tp){
g[u].a[1][0]=a[u];g[u].a[1][1]=-INF;
L[u]=R[u]=++dfn;R[tp]=dfn;id[dfn]=u;top[u]=tp;
if(son[u])rdfs(son[u],tp);
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]&&v!=son[u]){
rdfs(v,v);
g[u].a[0][0]+=max(f[v][0],f[v][1]);
g[u].a[1][0]+=f[v][0];
}
g[u].a[0][1]=g[u].a[0][0];
}
void update(int u,int val){
g[u].a[1][0]+=val-a[u];a[u]=val;
while(u){
Matrix lst=seg.query(1,1,n,L[top[u]],R[top[u]]);
seg.modify(1,1,n,L[u]);
Matrix now=seg.query(1,1,n,L[top[u]],R[top[u]]);
u=fa[top[u]];
g[u].a[0][0]+=max(now.a[0][0],now.a[1][0])-max(lst.a[0][0],lst.a[1][0]);
g[u].a[1][0]+=now.a[0][0]-lst.a[0][0];
g[u].a[0][1]=g[u].a[0][0];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",a+i);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1);rdfs(1,1);seg.build(1,1,n);
for(int i=1,u,val;i<=m;i++){
scanf("%d%d",&u,&val);
update(u,val);
Matrix ans=seg.query(1,1,n,1,R[1]);
printf("%d\n",max(ans.a[0][0],ans.a[1][0]));
}
return 0;
}
点击查看K题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5,INF=1e9+7;
int n,m;ll a[N],f[N];char op;
int head[N],nxt[N<<1],ver[N<<1],tot;
void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
struct Matrix{
ll a[2][2];
Matrix (){memset(a,0x3f,sizeof(a));}
Matrix operator *(const Matrix&b)const{
Matrix c;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
c.a[i][j]=min(c.a[i][j],a[i][k]+b.a[k][j]);
return c;
}
}g[N];
int fa[N],siz[N],top[N],L[N],dfn,R[N],son[N],id[N];
void dfs(int u){
siz[u]=1;
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]){
fa[v]=u;dfs(v);siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
f[u]+=min(f[v],a[v]);
}
if(!nxt[head[u]])f[u]=INF;
}
void rdfs(int u,int tp){
g[u].a[0][1]=a[u];g[u].a[0][0]=g[u].a[1][1]=0;
L[u]=++dfn;id[dfn]=u;R[tp]=dfn;top[u]=tp;
if(son[u])rdfs(son[u],tp);
else g[u].a[0][0]=INF;
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]&&v!=son[u]){
rdfs(v,v);
g[u].a[0][0]+=min(f[v],a[v]);
}
}
struct SegmentTree{
Matrix a[N<<2];
#define ls p<<1
#define rs p<<1|1
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){a[p]=g[id[l]];return;}
build(ls,l,mid);
build(rs,mid+1,r);
a[p]=a[ls]*a[rs];
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return a[p];
if(R<=mid)return query(ls,l,mid,L,R);
if(L>mid)return query(rs,mid+1,r,L,R);
return query(ls,l,mid,L,R)*query(rs,mid+1,r,L,R);
}
void modify(int p,int l,int r,int x){
if(l==r){a[p]=g[id[l]];return;}
if(x<=mid)modify(ls,l,mid,x);
else modify(rs,mid+1,r,x);
a[p]=a[ls]*a[rs];
}
#undef ls
#undef rs
#undef mid
}seg;
void update(int u,int val){
g[u].a[0][1]+=val;a[u]+=val;
while(u){
Matrix lst=seg.query(1,1,n,L[top[u]],R[top[u]]);
seg.modify(1,1,n,L[u]);
Matrix now=seg.query(1,1,n,L[top[u]],R[top[u]]);
u=fa[top[u]];
g[u].a[0][0]+=min(now.a[0][0],now.a[0][1])-min(lst.a[0][0],lst.a[0][1]);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lld",a+i);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1);rdfs(1,1);seg.build(1,1,n);
scanf("%d",&m);
for(int i=1,u,val;i<=n;i++){
while(op=getchar(),op!='Q'&&op!='C');
scanf("%d",&u);
if(op=='Q'){
Matrix ans=seg.query(1,1,n,L[u],R[top[u]]);
printf("%lld\n",min(ans.a[0][0],ans.a[0][1]));
}
else{scanf("%d",&val);update(u,val);}
}
return 0;
}
点击查看L题代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;const ll INF=1e18;
int n,m,p[N];ll f[N][2];char type[5];
int head[N],nxt[N<<1],ver[N<<1],tot;
void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
struct Matrix{
ll a[2][2];
Matrix (){a[0][0]=a[0][1]=a[1][0]=a[1][1]=INF;}
Matrix operator *(const Matrix&b)const{
Matrix c;
c.a[0][0]=min(a[0][0]+b.a[0][0],a[0][1]+b.a[1][0]);
c.a[1][0]=min(a[1][0]+b.a[0][0],a[1][1]+b.a[1][0]);
c.a[0][1]=min(a[0][0]+b.a[0][1],a[0][1]+b.a[1][1]);
c.a[1][1]=min(a[1][0]+b.a[0][1],a[1][1]+b.a[1][1]);
return c;
}
}g[N];
int fa[N],top[N],siz[N],L[N],dfn,R[N],son[N],id[N];
void dfs(int u){
f[u][1]=p[u];siz[u]=1;
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]){
fa[v]=u;dfs(v);siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
f[u][0]+=f[v][1];
f[u][1]+=min(f[v][0],f[v][1]);
}
}
void rdfs(int u,int tp){
g[u].a[0][0]=p[u];g[u].a[1][0]=0;
L[u]=++dfn;id[dfn]=u;top[u]=tp;R[tp]=dfn;
if(son[u])rdfs(son[u],tp);
for(int i=head[u],v;i;i=nxt[i])
if((v=ver[i])!=fa[u]&&v!=son[u]){
rdfs(v,v);
g[u].a[0][0]+=min(f[v][0],f[v][1]);
g[u].a[1][0]+=f[v][1];
}
g[u].a[0][1]=g[u].a[0][0];
}
struct SegmentTree{
Matrix a[N<<2];
#define mid (l+r>>1)
void build(int p,int l,int r){
if(l==r){a[p]=g[id[l]];return;}
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
a[p]=a[p<<1]*a[p<<1|1];
}
void modify(int p,int l,int r,int x){
if(l==r){a[p]=g[id[l]];return;}
if(x<=mid)modify(p<<1,l,mid,x);
else modify(p<<1|1,mid+1,r,x);
a[p]=a[p<<1]*a[p<<1|1];
}
Matrix query(int p,int l,int r,int L,int R){
if(l>=L&&r<=R)return a[p];
if(R<=mid)return query(p<<1,l,mid,L,R);
if(L>mid)return query(p<<1|1,mid+1,r,L,R);
return query(p<<1,l,mid,L,R)*query(p<<1|1,mid+1,r,L,R);
}
#undef mid
}seg;
void update(int u,int op,Matrix c){
if(op==1)g[u].a[1][0]=INF;
else if(op==2)g[u]=c;
else g[u].a[0][0]=g[u].a[0][1]=INF;
while(u){
Matrix lst=seg.query(1,1,n,L[top[u]],R[top[u]]);
seg.modify(1,1,n,L[u]);
Matrix now=seg.query(1,1,n,L[top[u]],R[top[u]]);
u=fa[top[u]];
g[u].a[0][0]+=min(now.a[0][0],now.a[1][0])-min(lst.a[0][0],lst.a[1][0]);
g[u].a[1][0]+=now.a[0][0]-lst.a[0][0];g[u].a[0][1]=g[u].a[0][0];
}
}
int main(){
// freopen("defense.in","r",stdin);
// freopen("defense.out","w",stdout);
scanf("%d%d",&n,&m);scanf("%s",type);
for(int i=1;i<=n;i++)scanf("%d",p+i);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1);rdfs(1,1);seg.build(1,1,n);
for(int i=1,a,x,b,y;i<=m;i++){
scanf("%d%d%d%d",&a,&x,&b,&y);
Matrix tmpa=g[a];update(a,x,tmpa);
Matrix tmpb=g[b];update(b,y,tmpb);
Matrix ans=seg.query(1,1,n,1,R[1]);
ll res=min(ans.a[0][0],ans.a[1][0]);
printf("%lld\n",res>1e15?-1:res);
update(b,2,tmpb);update(a,2,tmpa);
}
return 0;
}

Solution Set - 矩阵加速的更多相关文章

  1. [BZOJ 4818/LuoguP3702][SDOI2017] 序列计数 (矩阵加速DP)

    题面: 传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4818 Solution 看到这道题,我们不妨先考虑一下20分怎么搞 想到暴力,本蒟 ...

  2. HDU 5564 Clarke and digits 状压dp+矩阵加速

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5564 题意: 求长度在[L,R]范围,并且能整除7的整数的总数. 题解: 考虑最原始的想法: dp[ ...

  3. 【 CodeForces - 392C】 Yet Another Number Sequence (二项式展开+矩阵加速)

    Yet Another Number Sequence Description Everyone knows what the Fibonacci sequence is. This sequence ...

  4. 【HDU 3483】 A Very Simple Problem (二项式展开+矩阵加速)

    A Very Simple Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

  5. 【HDU3802】【降幂大法+矩阵加速+特征方程】Ipad,IPhone

    Problem Description In ACM_DIY, there is one master called “Lost”. As we know he is a “-2Dai”, which ...

  6. C++矩阵加速经典题目:Warcraft III 守望者的烦恼 [vijos 1067]

    Warcraft III 守望者的烦恼 背景 守望者-warden,长期在暗夜精灵的的首都艾萨琳内担任视察监狱的任务,监狱是成长条行的,守望者warden拥有一个技能名叫"闪烁", ...

  7. LuoGu P1939 【模板】矩阵加速(数列)

    板子传送门 矩阵快速幂学完当然要去搞一搞矩阵加速啦 (矩阵加速相对于矩阵快速幂来说就是多了一个构造矩阵的过程) 关于怎样来构造矩阵,这位大佬讲的很好呢 构造出矩阵之后,我们再去用矩阵快速幂乘出来,取[ ...

  8. Luogu P3390 【模板】矩阵快速幂&&P1939 【模板】矩阵加速(数列)

    补一补之前的坑 因为上次关于矩阵的那篇blog写的内容太多太宽泛了,所以这次把一些板子和基本思路理一理 先看这道模板题:P3390 [模板]矩阵快速幂 首先我们知道矩阵乘法满足结合律而不满足交换律的一 ...

  9. P1939【模板】矩阵加速(数列)

    P1939[模板]矩阵加速(数列)难受就难受在a[i-3],这样的话让k=3就好了. #include<iostream> #include<cstdio> #include& ...

  10. CF718C Sasha and Array 线段树+矩阵加速

    正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...

随机推荐

  1. 11.硬核的volatile考点分析

    大家好,我是王有志.关注王有志,一起聊技术,聊游戏,聊在外漂泊的生活. 今天我们学习并发编程中另一个重要的关键字volatile,虽然面试中它的占比低于synchronized,但依旧是不可忽略的内容 ...

  2. #分块,可撤销并查集#洛谷 5443 [APIO2019]桥梁

    题目 分析 最直接的做法就是在线一边修改边权,询问直接全部重排, 然后用可撤销并查集维护连通块大小,这样时间复杂度为 \(O(qm)\) 同样尽量让大部分的边不需要修改边权,那么每 \(B\) 个操作 ...

  3. Bootstrap实战 - 评论列表

    一.介绍 社交媒体网站盛行,人们常常会使用评论表达自己的观点,评论功能已然成为网站的一部分. 二.知识点 2.1 媒体对象 官方解释:这是一个抽象的样式,用以构建不同类型的组件,这些组件都具有在文本内 ...

  4. 12个月大厂主机免费领AWS Azure Google-Cloud还不快到碗里来

    目录 简介 AWS Azure Google Cloud Oracle 总结 简介 最近有个朋友问我哪里有免费主机可以领,说实话这个问题也困扰了我很久,之前也在网上寻找免费主机,可是免费的基本上都有一 ...

  5. OpenHarmony 技术日直播回顾丨共建新技术,开拓新领域

    4月25日,"共建新技术,开拓新领域"OpenAtom OpenHarmony(以下简称"OpenHarmony")技术日在深圳顺利召开.OpenHarmony ...

  6. SQL 查询优化指南:SELECT、SELECT DISTINCT、WHERE 和 ORDER BY 详解

    SELECT 关键字 SQL的SELECT语句用于从数据库中选择数据.SELECT语句的基本语法如下: SELECT column1, column2, ... FROM table_name; 其中 ...

  7. Python 函数:定义、调用、参数、递归和 Lambda 函数详解

    函数是一段代码块,只有在调用时才会运行.您可以将数据(称为参数)传递给函数. 函数可以返回数据作为结果. 创建函数 在Python中,使用def关键字定义函数: 示例 def my_function( ...

  8. JDBC驱动连接MogDB/opengauss

    JDBC 驱动连接 MogDB/opengauss 一.环境说明 [root@node1 ~]# cat /etc/redhat-release CentOS Linux release 7.6.18 ...

  9. 如何跑各种check

    如何进行 Fastcheck? 首先,导入环境变量: export CODE_BASE=/data/openGauss-server export BINARYLIBS=/data/openGauss ...

  10. 【有奖互动】开发者版本新特性,你期待哪些更新?#HDC.Together2023#

    <hdc.together< span="">>华为开发者大会2023再次启航,将于8月4日~6日在中国松山湖举办,承载万千期待,开启崭新时代.聚焦新版本. ...