A[HDU2604]求不含子串010和000的,长为n的01序列数。
B[HDU6470]数列{an}:a1=1,a2=2,an=an−1+2an−2+n3,给定n,求an。
C[HDU3306]数列{an}:a0=a1=1,an=xan−1+yan−2,给定n,x,y,求前n项平方和。
D[HDU2276]01环,每轮操作改变所有1左边位置的值,求m轮后的结果。
E[LibreOJ#6208]给定一棵树,点有两个权k,t,支持对某个点到根的路径修改k+d→k,t+k×d→t,询问单点的t。
F[LibreOJ#2980]给定三个数列a,b,c,支持以下操作:ai+bi→ai,bi+ci→bi,ci+ai→ci,ai+v→ai,bi×v→bi,v→ci,询问a,b,c的区间和。
G[CF750E]给定数字串,对某个子串,求其至少删去多少个字符,才能使剩余串含子序列2017,但不含子序列2016。
H[洛谷P6573]给定有向图,边有权,边(x,y)满足⌊yk⌋=1+⌊xk⌋,1≤k≤5。求从u到v的最小路程。多组询问。
I[洛谷P7359]给定树,每条边有距离a,水流影响b以及水流向。通过一条边,走路耗时a,顺流而下耗时a−b,逆流而上耗时a+b。每次上船需要时间l。求从u到v的最小时间。多组询问。
J[洛谷P4719]一棵树,点有权,单点修改,求最大权独立集。
K[洛谷P6021]一棵树,点有权,单点修改,求在某棵子树中选出一些点,使得所有叶子与根不连通的最小权值和。
L[洛谷P5024]一棵树,点有权,给定某两个点的选择状况,求最小权覆盖集。
A维护6×6的矩阵,代表可能的6种结尾三个数。然后用矩阵快速幂。
B移项,求出一个三次函数f使an+f(n)=(an−1+f(n−1))+2(an−2+f(n−2)),然后用矩阵快速幂求an+f(n)。
C维护a2n−1,a2n−2,an−1an−2,sn−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(){ |
| |
| 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(){ |
| |
| |
| 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; |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具