[CSP-S Simulation Test]: Number of (segment tree optimization DP)

Topic Portal (internal title 96)


Input Format

  A first line integer $ n $, $ n-$ next three lines each an integer of $ a_i, b_i, w_i $.


Output Format

  An integer representing the maximum line weights and.


Sample

Sample input:

5
4 4 1
2 3 3
1 5 1
4 2 2
5 2 3

Sample output:

7


Data range and tips

  For $ 10 \% $ data, $ n \ leqslant 8 $.
  For $ 40 \% $ data, $ n \ leqslant 200 $.
  For $ 70 \% $ data, $ n \ leqslant 3,000 $.
  For $ 100 \% $ data, $ 1 \ leqslant n \ leqslant 10 ^ 5, 1 \ leqslant a_i, b_i, w_i \ leqslant 10 ^ 9 $.


answer

Consider first how to select the best, according to the $ a_i + b_i $ small to large and by $ min (a_i, b_i) $ small to large order can be accessed through this problem (I do not know why).

It found that $ a_i, b_i $ only related to its size, but its specific value has nothing to do, so a direct discrete enough.

Consider $ DP $, defined $ dp [i] [j] $ is selected to represent one of $ I $, $ \ min (a_i) $ $ J $ is the greatest contribution.

Transfer can write:

$$dp[i][j]=\max(dp[i-1][j])$$

$$dp[i][\max(j,a[i])]=\max(dp[i-1][j]+w[i])$$

There is clearly space or time can not be tolerated, consider optimizing.

In fact, found a range of plus of course, can then be used to optimize segment tree.

Time complexity: $ \ Theta (n \ log cnt) $ ($ where $ is the number of different CNT of a_i $ and $ $ $ of B_i).

Expectations score: $ 100 $ points.

Actual score: $ 100 $ points.


Code time

#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
unordered_map<int,int>mp;
struct rec{int a,b,w;}e[100001];
int n;
int cnt;
int que[200001];
long long tr[1000000],lz[1000000];
bool cmp(rec a,rec b){return a.a+a.b<b.a+b.b;}
void pushup(int x){tr[x]=max(tr[L(x)],tr[R(x)]);}
void pushdown(int x)
{
	tr[L(x)]+=lz[x];
	tr[R(x)]+=lz[x];
	lz[L(x)]+=lz[x];
	lz[R(x)]+=lz[x];
	lz[x]=0;
}
void add(int x,int l,int r,int L,int R,int w)
{
	if(r<L||R<l)return;
	if(L<=l&&r<=R)
	{
		tr[x]+=w;
		lz[x]+=w;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(x);
	add(L(x),l,mid,L,R,w);
	add(R(x),mid+1,r,L,R,w);
	pushup(x);
}
void upd(int x,int l,int r,int k,long long w)
{
	if(l==r)
	{
		tr[x]=max(tr[x],w);
		return;
	}
	int mid=(l+r)>>1;pushdown(x);
	if(k<=mid)upd(L(x),l,mid,k,w);
	else upd(R(x),mid+1,r,k,w);
	pushup(x);
}
long long ask(int x,int l,int r,int L,int R)
{
	if(r<L||R<l)return -0x3f3f3f3f3f3f3f3f;
	if(L<=l&&r<=R)return tr[x];
	int mid=(l+r)>>1;pushdown(x);
	return max(ask(L(x),l,mid,L,R),ask(R(x),mid+1,r,L,R));
}
int main()
{
	scanf("%lld",&n);int top=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].w);
		que[++top]=e[i].a;que[++top]=e[i].b;
	}
	sort(que+1,que+top+1);
	for(int i=1;i<=top;i++)if(que[i]!=que[i-1])mp[que[i]]=++cnt;
	for(int i=1;i<=n;i++){e[i].a=mp[e[i].a];e[i].b=mp[e[i].b];}
	sort(e+1,e+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		long long flag=ask(1,1,cnt,1,min(e[i].a,e[i].b));
		add(1,1,cnt,e[i].a,e[i].b,e[i].w);
		upd(1,1,cnt,e[i].a,flag+e[i].w);
	}
	printf("%lld",tr[1]);
	return 0;
}

rp ++

Guess you like

Origin www.cnblogs.com/wzc521/p/11759013.html