zoukankan      html  css  js  c++  java
  • CF1557D Ezzat and Grid(线段树)

    CF1557D Ezzat and Grid

    前言

    线段树好题一个。

    解题思路

    我们首先先要对数据进行离散化,这是一个常规套路。

    正难则反,我们考虑 dp 。令 (f_i) 表示以 (i) 为结尾,最多可以选择多少行。显然,我们有转移方程:

    [f_i=maxlimits_{j<i operatorname{and} g(i,j)} f_j+1 ]

    其中 (g(i,j)) 为一个布尔函数,表示第 (i,j) 行是否可以相邻。

    这显然是一个 (O(n^3)) 级别的算法,我们考虑优化一下,可以用线段树。

    我们假设现在考虑已经求出对于 (jin [1,i]) 中的所有 (f_j),我们线段树维护的是目前,区间所被覆盖的行中 (f_i) 值最大的那一个,这样我们在求解 (f_{i+1})​ 时,可以利用线段树上的信息了。

    最后答案就是 (n-maxlimits_{i=1}^n f_i)

    求解方案的话,只要记录一下决策点即可。

    时间复杂度 (O(nlog n))。线段树帮助我们省去了枚举 (j) 和计算 (g) 函数的时间。

    代码

    注意有几处等于号一定要有,否则会错。

    别问我怎么知道。

    22次的提交记录告诉我的

    原因的话,是因为可能因为 pushup 操作导致父节点的 (maxx)​ 值已经正确,但是另外一个子节点无法更新到。

    这话很抽象,最好在实践中理解。。。。。

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    const int MAXN=3e5+10; 
    
    int n,m,len,cnt;
    struct segment {
    	int maxx,lazy;
    }s[MAXN<<3];
    struct sgm {
    	int id,l,r;
    }sm[MAXN];
    int num[MAXN<<1],f[MAXN],g[MAXN];
    bool vis[MAXN];
    vector<sgm> vec[MAXN];
    
    void pushdown(int l,int r,int p) {
    	if(l==r) {
    		return ;
    	}
    	int mid=(l+r)>>1;
    	if(f[s[p].lazy]>=f[s[p<<1].maxx]) {
    		s[p<<1].maxx=s[p].lazy;
    		s[p<<1].lazy=s[p].lazy;
    	}
    	if(f[s[p].lazy]>=f[s[p<<1|1].maxx]) {
    		s[p<<1|1].maxx=s[p].lazy;
    		s[p<<1|1].lazy=s[p].lazy;
    	}
    	s[p].lazy=0;
    }
    segment pushup(segment lft,segment rgt) {
    	segment ret=s[0];
    	if(f[lft.maxx]>f[rgt.maxx]) {
    		ret.maxx=lft.maxx;
    	}
    	else {
    		ret.maxx=rgt.maxx;
    	}
    	return ret;
    }
    
    void modify(int l,int r,int p,int x,int y,int val) {
    	if(r<x||y<l) {
    		return ;
    	}
    	pushdown(l,r,p);
    	if(x<=l&&r<=y) {
    		if(f[val]>=f[s[p].maxx]) {
                //here
    			s[p].maxx=val;
    			s[p].lazy=val;
    		}
    		return ;
    	}
    	
    	int mid=(l+r)>>1;
    	modify(l,mid,p<<1,x,y,val);
    	modify(mid+1,r,p<<1|1,x,y,val);
    	s[p]=pushup(s[p<<1],s[p<<1|1]);
    }
    segment query(int l,int r,int p,int x,int y) {
    	if(r<x||y<l) {
    		return s[0];
    	}
    	pushdown(l,r,p);
    	if(x<=l&&r<=y) {
    		return s[p];
    	}
    	
    	int mid=(l+r)>>1;
    	return pushup(query(l,mid,p<<1,x,y),query(mid+1,r,p<<1|1,x,y));
    }
    
    int get(int x) {
    	return lower_bound(num+1,num+len+1,x)-num;
    }
    
    signed main() {
    
    	cin>>n>>m;
    	for(int i=1;i<=m;i++) {
    		sm[i].id=read();num[++cnt]=sm[i].l=read();num[++cnt]=sm[i].r=read();
    	}
    	sort(num+1,num+cnt+1);
    	len=unique(num+1,num+cnt+1)-num-1;
    	
    	for(int i=1;i<=m;i++) {
    		sm[i].l=get(sm[i].l);
    		sm[i].r=get(sm[i].r);
    		vec[sm[i].id].push_back(sm[i]);
    	}
    	
    	int tp=0,maxx=0;
    	for(int i=1;i<=n;i++) {
    		if(i==6) {
    			int hhh;
    			hhh++;
    		}
    		segment ans=s[0];
    		int sz=vec[i].size();
    		for(int j=0;j<sz;j++) {
    			ans=pushup(ans,query(1,len,1,vec[i][j].l,vec[i][j].r));
    		}
    		f[i]=f[ans.maxx]+1;
    		g[i]=ans.maxx;
    		//cout<<f[i]<<" "<<g[i]<<endl;
    		if(f[i]>maxx) {
    			maxx=f[i];
    			tp=i;
    		}
    		
    		for(int j=0;j<sz;j++) {
    			modify(1,len,1,vec[i][j].l,vec[i][j].r,i);
    		}
    	}
    	
    	int ans=n;
    	while(tp) {
    		ans--;
    		vis[tp]=1;
    		tp=g[tp];
    	}
    	
    	cout<<ans<<endl;
    	for(int i=1;i<=n;i++) {
    		if(!vis[i]) {
    			printf("%d ",i);
    		}
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    css常用属性
    html常用标签
    通讯录管理
    消息推送
    企业微信API开发前准备
    毕业设计-基于图像处理的垃圾分类系统2020.03.17
    毕业设计-基于图像处理的垃圾分类系统2020.03.15
    毕业设计-基于图像处理的垃圾分类系统2020.03.14
    毕业设计-基于图像处理的垃圾分类系统2020.03.13
    毕业设计-基于图像处理的垃圾分类系统2020.03.12
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/CF1557D.html
Copyright © 2011-2022 走看看