• ds套dp——考虑位置转移or值域转移:CF1762F


    https://www.luogu.com.cn/problem/CF1762F

    • 分析性质,就是我们选的数要么递增,要么递减(非严格)
    • 然后很明细是ds套dp, f i f_i fi 表示以 i i i 开头的答案
    • 然后考虑如何转移(ds套dp难点反而在转移而不是状态,因为要考虑如何和ds结合)
    • 转移的话,要么从位置考虑,要么从值域考虑
    • 从值域考虑,就从后面比它大且最小的转移,似乎不知道怎么搞
    • 从位置考虑,就是从第一个在 [ a i , a i + k ] [a_i,a_i+k] [ai,ai+k] 内的数转移。我们考虑会漏掉值域在 [ a i + 1 , a j − 1 ] [a_i+1,a_j-1] [ai+1,aj1] 的数,但这可以直接套ds来做了。至于大于 a j a_j aj 的会在 f j f_j fj 里算
    #include
    using namespace std;
    #define int long long
    inline int read(){int x=0,f=1;char ch=getchar(); while(ch<'0'||
    ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){
    x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
    #define Z(x) (x)*(x)
    #define pb push_back
    //mt19937 rand(time(0));
    //mt19937_64 rand(time(0));
    //srand(time(0));
    #define N 500010
    //#define M
    //#define mo
    struct node {
    	int x, id; 
    	bool operator < (const node &A) const {
    		return id < A.id; 
    	}
    }b[N]; 
    int n, m, i, j, k, T;
    int ans, a[N], mp[N], nxt[N], f[N], l; 
    set<node>s; 
    set<node>::iterator it; 
    
    struct Binary_tree {
    	int cnt[N]; 
    	void add(int x, int y) {
    		while(x<N) cnt[x]+=y, x+=x&-x; 
    	}
    	int que(int x) {
    		int ans = 0; while(x) ans+=cnt[x], x-=x&-x; 
    		return ans; 
    	}
    }Bin;
    
    void calc() {
    	for(i=1; i<=n; ++i) b[i].x = a[i], b[i].id = i; 	
    	auto cmp = [&] (node x, node y) -> bool {
    		if(x.x == y.x) return x.id > y.id; 
    		return x.x > y.x; 
    	}; 
    	sort(b+1, b+n+1, cmp); 
    	s.clear(); 
    	for(i=l=1; i<=n; ++i) {
    		while(b[l].x>b[i].x+k) s.erase(b[l]), ++l; 
    		it = s.upper_bound({0, b[i].id}); 
    		if(it == s.end()) nxt[b[i].id] = 0;  
    		else nxt[b[i].id] = (it -> id); 
    		s.insert(b[i]); 
    	}
    //	for(i = 1; i <= n; ++i) printf("%d ", nxt[i]); printf("\n"); 
    	for(i=n; i>=1; --i) {
    		j=nxt[i]; 
    		f[i]=f[j]+1; 
    		if(nxt[i]==0) f[i]+=Bin.que(a[i]+k)-Bin.que(a[i]-1); 
    		else f[i]+=Bin.que(a[nxt[i]]-1)-Bin.que(a[i]-1); 
    		ans+=f[i]; Bin.add(a[i], 1); 
    //		printf("%lld (%lld %lld)", f[i], f[j]); 
    	}
    //	printf("\n"); 
    	for(i=1; i<=n; ++i) Bin.add(a[i], -1); 
    }
    
    signed main()
    {
    //	freopen("in.txt", "r", stdin);
    //	freopen("out.txt", "w", stdout);
    	T=read();
    	while(T--) {
    		n=read(); k=read(); ans=0; 
    		for(i=1; i<=n; ++i) {
    			a[i]=read(), mp[a[i]]++, ans-=mp[a[i]]; 
    		}
    //		printf("> %lld\n", ans); `
    		calc(); 
    		reverse(a+1, a+n+1); 
    		calc(); 
    		for(i=1; i<=n; ++i) mp[a[i]]=0; 
    		printf("%lld\n", ans); 
    	}
    
    	return 0;
    }
    
    
    
    • 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
  • 相关阅读:
    springboot基于WEB的高校文档打印系统毕业设计源码101004
    JavaScript While循环
    linux 安装docker
    东郊到家app小程序公众号软件开发预约同城服务系统成品源码部署
    【PDF提取页面】使用Adobe Acrobat提取PDF文档的某几个页面另存
    蓝桥杯python组--基础训练---求输入的第n个,斐波那契数
    员工离职倾向尽在公司掌握,争议发生后,监控系统研发商悄悄下架相关服务
    Spring Cache
    这个Python库助力pandas智能可视化分析
    Redis通用命令和key的层级结构
  • 原文地址:https://blog.csdn.net/zhangtingxiqwq/article/details/133691573