zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15039523.html
Copyright © 2011-2022 走看看