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. Linux开发相关命令整理

    1. 反转shell 2. ldd 3. objdump 4. ldconfig 5. telnet 6. nc 7. netstat 8. ss 9. tcpdump 10. lsof 11. st ...

  2. windows系统python3.6(Anaconda3)安装对应版本 torch、torchvision

    一.官网下载 .whl 文件 https://download.pytorch.org/whl/torch_stable.html 二.使用pip命令安装 打开你的anaconda,选择对应虚拟环境终 ...

  3. #树形依赖背包,点分治#BZOJ 4182 Shopping

    题目 给定一棵大小为 \(n\) 的树,每个点代表一种物品,其具有体积.价值和数量的属性, 现在选择一个连通块,使得里面所有点都被选中且体积不超过 \(m\),问最大价值. \(n\leq 500,m ...

  4. #轻重链剖分,交互#LOJ 6669 Nauuo and Binary Tree

    题目 有一棵大小为\(n\)只知道根节点为1的二叉树, 可以不超过\(3*10^4\)询问两点之间距离, 最后输出除了点1以外其余点的祖先 \(n\leq 3000\) 分析 \(O(n^2)\)的时 ...

  5. OpenHarmony应用实现二维码扫码识别

     本文转载自<OpenHarmony应用实现二维码扫码识别>,作者zhushangyuan_ 概念介绍 二维码的应用场景非常广泛,在购物应用中,消费者可以直接扫描商品二维码,浏览并购买产品 ...

  6. 全面指南:技术写作与编辑工具 Markdown、Git 研究工具

    技术写作工具 在技术写作领域,"工具"是指技术写作者用于创建.管理和发布高质量技术文档的各种软件和应用程序.这包括文字处理器.桌面出版应用程序.XML 编辑器.内容管理系统等等.一 ...

  7. Python 内置数据类型详解

    内置数据类型 在编程中,数据类型是一个重要的概念. 变量可以存储不同类型的数据,不同类型可以执行不同的操作. Python默认内置了以下这些数据类型,分为以下几类: 文本类型:str 数值类型:int ...

  8. Mac系统,Qt工程转xcode工程,打包pkg

    序言: 程序使用Qt开发,程序主要功能是调用摄像头.需要打包成pkg给到用户安装,打包用到的是xcode. 实际操作: 一.Qt工程转xcode工程 // 打开终端,cd到项目根目录(CamScan. ...

  9. 攻防世界 debug

    题目 分析过程 丢到PE里面 一开始,我看到下面的脱壳提示,以为是我没见过的壳,下载了相关工具脱壳--发现脱了后又出现没见过的脱壳提示,根据提示脱壳弄出来的东西怪怪的 卡题,查了资料 学到一个新知识点 ...

  10. [Java SE] 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算?

    0 问题描述 经典问题:超出Java Long型(8字节/64位)的二进制比特流数据如何进行大数的数值计算? 近期工作上遇到了这个问题:需要将一个无符号数.且位长>=8字节(等于8字节时,首位b ...