• 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);
    }
  • 相关阅读:
    idea无法clean报错Error running 'lizi-user-api [clean]': No valid Maven installation found. Either set the home directory in the configuration dialog or set the M2_HOME environment variable on your system.
    maven项目无法下载依赖jar包
    JPA封装baseDao
    forward和redirect的区别
    java的三个体系
    Java基本修饰符
    SpringMVC 中,当前台传入多个参数时,可将参数封装成一个bean类
    注解@RequestParam——取请求参数
    冒泡排序
    为什么要使用线程池?
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15039523.html
Copyright © 2020-2023  润新知