zoukankan      html  css  js  c++  java
  • Codeforces 1129 D. Isolation

    Codeforces 1129 D. Isolation

    解题思路

    (f(l,r))([l,r]) 中之出现一次的元素个数,然后可以得到暴力 ( ext{dp}) 的式子。

    [dp[i]=sum_{j=i-1}[f(j+1,i)leq k]dp[j] ]

    实际上任意一个位置为左端点,(i) 为右端点的 (f(l,r)) 值是可以动态维护的。

    ((i-1) ightarrow i) ,设 (pre[i])(i) 之前上一个出现 (a[i]) 的位置,那么相当与 (f(pre[i]+1,i)dots f(i,i)) 的值会 (+1)(f(pre[pre[i]]+1,i)dots f(pre[i],i)) 的值会 (-1) ,分个块维护一下所有当前 (f) 值小于等于 (k)(dp) 值之和即可,复杂度 (mathcal O(nsqrt n))

    code

    /*program by mangoyang*/
    #include <bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int ch = 0, f = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    const int M = 205, N = 100005, L = 100000, mod = 998244353;
    int a[N], bel[N], tag[N], tot[N], ans[M], s[M][N<<1], pre[N], lst[N], dp[N], n, k, T;
    inline void up(int &x, int y){
    	x = x + y >= mod ? x + y - mod : x + y;
    }
    inline void gao(int i, int x){
    	up(s[bel[i]][L+tot[i]], mod - dp[i]);
    	tot[i] += x;
    	up(s[bel[i]][L+tot[i]], dp[i]);
    	if(x == 1 && tot[i] + tag[bel[i]] == k + 1) 
    		up(ans[bel[i]], mod - dp[i]);
    	if(x == -1 && tot[i] + tag[bel[i]] == k) 
    		up(ans[bel[i]], dp[i]);
    }
    inline void modify(int l, int r, int x){
    	if(bel[l] + 1 >= bel[r]){
    		for(int i = l; i <= r; i++) gao(i, x);
    		return;
    	}
    	for(int i = l; i < (bel[l] + 1) * T; i++) gao(i, x);
    	for(int i = bel[r] * T; i <= r; i++) gao(i, x);
    	for(int i = bel[l] + 1; i < bel[r]; i++){
    		if(x == 1) up(ans[i], mod - s[i][L+k-tag[i]]);
    		if(x == -1) up(ans[i], s[i][L+k-tag[i]+1]);
    		tag[i] += x;
    	}
    }
    inline int query(int l, int r){
    	int res = 0;
    	if(bel[l] + 1 >= bel[r]){
    		for(int i = l; i <= r; i++)
    			if(tot[i] + tag[bel[i]] <= k) up(res, dp[i]);
    		return res;
    	}
    	for(int i = l; i < (bel[l] + 1) * T; i++) 
    		if(tot[i] + tag[bel[i]] <= k) up(res, dp[i]);
    	for(int i = bel[r] * T; i <= r; i++) 
    		if(tot[i] + tag[bel[i]] <= k) up(res, dp[i]);
    	for(int i = bel[l] + 1; i < bel[r]; i++) up(res, ans[i]);
    	return res;
    }
    int main(){
    	read(n), read(k), T = 500;
    	for(int i = 0; i <= n; i++) bel[i] = i / T;
    	for(int i = 1; i <= n; i++) read(a[i]);
    	dp[0] = 1;
    	up(ans[bel[0]], dp[0]);
    	up(s[bel[0]][L-tag[bel[0]]], dp[0]);
    	for(int i = 1; i <= n; i++){
    		pre[i] = lst[a[i]], lst[a[i]] = i;
    		modify(pre[i], i - 1, 1);
    		if(pre[i]) modify(pre[pre[i]], pre[i] - 1, -1);
    		dp[i] = query(0, i - 1);
    		up(ans[bel[i]], dp[i]);
    		up(s[bel[i]][L-tag[bel[i]]], dp[i]);
    	}
    	cout << dp[n];
    	return 0;
    }
    
  • 相关阅读:
    ORM框架
    优酷项目1
    新年第一天
    前端第十天
    前端第九天
    前端第八天
    前端第七天
    前端第六天
    前端第五天
    月亮与六便士
  • 原文地址:https://www.cnblogs.com/mangoyang/p/10441660.html
Copyright © 2011-2022 走看看