题解:P11233 [CSP-S 2024] 染色(民间数据)
Solution
容易想到
转移为
这个式子是不能直接优化的,我们需要贪心一下,其实第一个方程只需要找到最大的
每个
PS:可以不用树状数组,直接用一个标记维护全局加的操作,更新
Code
O(n \log n) (赛时代码)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5,M=1e6;
int t,n,a[N+5],tre[N+5],mp[N+5];
vector<int>g[M+5];
int lb(int x){return x&-x;}
void add(int x,int y){for(int i=x;i<=n;i+=lb(i))tre[i]+=y;}
int query(int x){int ret=0;for(int i=x;i>=1;i-=lb(i))ret+=tre[i];return ret;}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],g[a[i]].push_back(i),mp[i]=g[a[i]].size()-1;
int ans=0;
for(int i=1;i<=n;i++){
if(mp[i]){
int val=max(ans,query(g[a[i]][mp[i]-1]+1)+a[i]);
add(i,val),add(i+1,-val);
}
else add(i,ans),add(i+1,-ans);
int val=(a[i]==a[i-1])*a[i];
add(1,val),add(i,-val);
ans=max(ans+val,query(i));
}
cout<<ans<<'\n';
for(int i=1;i<=n;i++)tre[i]=0;
for(int i=1;i<=n;i++)g[a[i]].clear();
}
}
Thanks
在此感谢 zzzz1234567 大佬帮我将原本