1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include<stdio.h> #include<string.h> #include<map> #include<algorithm> using namespace std; #define lson l,m,rt*2 #define rson m+1,r,rt*2+1 int tree[350050*8]; int flag[350050*8]; int a[350050]; int last[350050]; int dp[350050]; int n,k; void build(int l,int r,int rt) { flag[rt]=0; if(l==r) { tree[rt]=dp[l]; flag[rt]=0; return; } int m=(l+r)>>1; build(lson); build(rson); } void pushdown(int l,int r,int rt) { if(flag[rt]) { int m=(l+r)/2; flag[rt*2]+=flag[rt]; flag[rt*2+1]+=flag[rt]; tree[rt*2]+=flag[rt]; tree[rt*2+1]+=flag[rt]; flag[rt]=0; } } void pushup(int rt) { tree[rt]=max(tree[rt<<1],tree[rt<<1|1]); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { return tree[rt]; } else { pushdown(l,r,rt); int m=(l+r)>>1; int ans=0; if(L<=m) { ans=max(ans,Query(L,R,lson)); } if(m<R) { ans=max(ans,Query(L,R,rson)); } pushup(rt); return ans; } } void update(int L,int R,int c,int l,int r,int rt) { if(L<=l&&r<=R) { tree[rt]+=c; flag[rt]+=c; return ; } pushdown(l,r,rt); int m=(l+r)/2; if(L<=m) { update(L,R,c,lson); } if(m<R) { update(L,R,c,rson); } pushup(rt); } int solve() { scanf("%d%d",&n,&k); memset(dp,0,sizeof(dp)); for(int i=1; i<=n; i++)scanf("%d",&a[i]); for(int i=1; i<=k; i++) { build(0,n,1); for(int j=1; j<=n; j++)dp[j]=0,last[a[j]]=0; for(int j=1; j<=n; j++) { update(last[a[j]],j-1,1,0,n,1); last[a[j]]=j; dp[j]=Query(0,j-1,0,n,1); } } printf("%d\n",dp[n]); return 0; } int main(){ char in[20]={"sub0.in"}; char out[20]={"sub0.out"}; for(int cas=0;cas<10;cas++){ freopen(in,"r",stdin);in[3]++; freopen(out,"w",stdout);out[3]++; solve(); } return 0; }
|