• P3097 [USACO13DEC]Optimal Milking G(线段树维护矩阵乘法)


    题意简述:给定n个点排成一排,每个点有一个点权,多次改变某个点的点权并将最大点独立集计入答案,输出最终的答案

    定义f(i,0)为第i个数不取,定义f(i,1)为第i个数取。

    转移式子:

    f(i,0)=max(f(i-1,0),f(i-1,1))
    f(i,1)=max(f(i-1,0)+a[i])

    可以用矩阵表示这个过程:
    0 a[i]
    0 -inf

    用线段树维护一下这个矩阵乘法,就做完了。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    typedef long long ll;
    struct matrix {
    	ll m[3][3];
    };
    void ccpy (matrix &x,matrix &y) {
    	for (int i=1;i<=2;i++) {
    		for (int j=1;j<=2;j++) {
    			x.m[i][j]=y.m[i][j];
    		}
    	}
    }
    void mul (matrix &ans,matrix a,matrix b) {
    	for (int i=1;i<=2;i++) {
    		for (int j=1;j<=2;j++) {
    			ans.m[i][j]=max(a.m[i][j],b.m[i][j]);
    		}
    	}
    	for (int k=1;k<=2;k++) {
    		for (int i=1;i<=2;i++) {
    			for (int j=1;j<=2;j++) {
    				ans.m[i][j]=max(ans.m[i][j],a.m[i][k]+b.m[k][j]);
    			}
    		}
    	}
    }
    int n,a[maxn],m;
    struct node {
    	int l,r;
    	matrix sum;
    }segTree[maxn<<2];
    void build (int i,int l,int r) {
    	segTree[i].l=l;
    	segTree[i].r=r;
    	if (l==r) {
    		segTree[i].sum.m[1][1]=0;
    		segTree[i].sum.m[1][2]=a[l];
    		segTree[i].sum.m[2][1]=0;
    		segTree[i].sum.m[2][2]=-1e10;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(i<<1,l,mid);
    	build(i<<1|1,mid+1,r);
    	mul(segTree[i].sum,segTree[i<<1].sum,segTree[i<<1|1].sum);
    }
    void up (int i,int p,int v) {
    	if (segTree[i].l==p&&segTree[i].r==p) {
    		a[segTree[i].l]=v;
    		segTree[i].sum.m[1][1]=0;
    		segTree[i].sum.m[1][2]=v;
    		segTree[i].sum.m[2][1]=0;
    		segTree[i].sum.m[2][2]=-1e10;
    		return;
    	}
    	int mid=(segTree[i].l+segTree[i].r)>>1;
    	if (p<=mid) up(i<<1,p,v);
    	if (p>mid) up(i<<1|1,p,v);
    	mul(segTree[i].sum,segTree[i<<1].sum,segTree[i<<1|1].sum);
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++) scanf("%d",a+i);
    	long long ans=0;
    	build(1,1,n);
    	while (m--) {
    		int x,y;
    		scanf("%d%d",&x,&y);
    		up(1,x,y);
    		ans+=max(segTree[1].sum.m[1][1],segTree[1].sum.m[1][2]);
    	}
    	printf("%lld
    ",ans);
    }
  • 相关阅读:
    第十章 Ingress
    第九章 Service
    第八章 资源控制器
    第一章 Xshell5评估期已过问题
    第七章 yaml格式
    第六章 资源清单
    第五章 配置私有仓库Harbor
    第四章 K8s部署安装
    36 SpringBoot 在系统配置文件中动态加载配置
    Java 集合、数组 任意个数数字相加等于一个指定的数
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15039523.html
Copyright © 2020-2023  润新知