• LOJ6698 一键挖矿


    一键挖矿

    2098 年 4 月,Terraria 发布了 1.7 版本更新。

    更新日志中显示,这个版本添加了一种新的机关,占用 (n imes m) 的矩形区域。将这个区域中第 (i) 行第 (j) 列的方块记作 (left<i,j ight>)

    每个方块有一个在 (1)(nm) 之间的权值,记作 (w_{left<i,j ight>}),所有方块的权值互不相同。你可以选定两个参数 (l,r),满足 (1le lle rle nm)。在此参数作用下,所有权值在 ([l,r]) 外的方块将会虚化,只留下所有权值在 ([l,r]) 内的方块。形式化地说,一个方块 (left<i,j ight>) 会被保留当且仅当 (lle w_{left<i,j ight>}le r)

    你发现 1.7 版本仍兼容七十年前已停止更新的 tModLoader v1.23.7。你高兴地载入修改日期为 2020/9/21 19:44 的 VeinMiner.tmod 一键挖矿 Mod,想要试试它能不能对新的机关起作用。

    一键挖矿 Mod 可以一次性采集所有与初始挖掘方块四连通未虚化的方块。也就是说,可以利用这个 Mod 采集所有的与初始挖掘方块在同一四连通块内的方块。

    但是因为 Terraria 1.7 对方块更新进行了优化,所以这个 Mod 有一个 bug:如果所有与初始挖掘方块四连通的方块没有形成一个矩形区域,则无法完整地把这些方块全部采集下来。

    你想知道有多少种选择参数 (l,r) 的方法,使得在参数作用下,能够使用一键挖矿 Mod 在不触发 bug 的情况下一次性采集所有未虚化的机关方块。

    对于所有测试点:(1le w_{left<i,j ight>}le nmle2 imes10^5)

    题解

    https://jklover.hs-blog.cf/2020/07/15/Loj-6698-一键挖矿/#more

    线段树.

    一维时是经典问题,但我们常用的单调栈 + 线段树做法并不能比较方便的搬到二维上,需要考虑另外一种条件转化.

    加入权值在区间 ([l,r]) 内的格子,令它们的颜色为黑色,其它的格子颜色为白色.

    考虑所有的 ((n+1) imes (m+1))(2 imes 2) 的小正方形(超出边界也算),则所有黑色格子形成一个矩形,当且仅当恰好有 (4) 个小正方形内部有 (1) 个黑色格子,并且没有任何一个小正方形内部有 (3) 个黑色格子.

    必要性是显然的,任何一个由黑色格子组成的矩形都满足以上条件.充分性可以这样考虑,初始时一定是有 (4) 个黑色格子,要求恰好有 (4) 个小正方形内部有 (1) 个黑色格子,就必须用黑色格子将它们连起来,形成矩形的边界,而此时角的地方会出现包含 (3) 个黑色格子的小正方形,只有将内部全部填满后才会消失,于是可以得出这个条件是充分必要的.

    有了这个结论,再来考虑如何计算答案.我们从小到大枚举 (r) ,并对每个 (lle r) 维护 (f(l)) ,表示将权值在 ([l,r]) 内的格子染黑后,有多少个小正方形内部有 (1) 个或 (3) 个黑色格子.不难发现 (f(l)ge 4,f(r)=4) 是恒成立的,根据上面的结论,我们只需要求有多少个 (f(l)=4) ,即最小值的个数.

    用线段树维护 (f) 以及最小值个数,每次 (r) 增加 (1) 时,会影响到周边的 (4)(2 imes 2) 的小正方形,在线段树上区间加即可.

    时间复杂度 (O(nmlog nm)) .

    CO int N=2e5+10;
    struct node {int min,cnt;};
    
    IN node operator+(CO node&a,CO node&b){
    	if(a.min!=b.min) return a.min<b.min?a:b;
    	return {a.min,a.cnt+b.cnt};
    }
    
    node tree[4*N];
    int tag[4*N];
    
    #define lc (x<<1)
    #define rc (x<<1|1)
    #define mid ((l+r)>>1)
    IN void put_tag(int x,int v){
    	tree[x].min+=v,tag[x]+=v;
    }
    IN void push_down(int x){
    	if(tag[x]){
    		put_tag(lc,tag[x]),put_tag(rc,tag[x]);
    		tag[x]=0;
    	}
    }
    void build(int x,int l,int r){
    	tree[x]={0,r-l+1};
    	if(l==r) return;
    	build(lc,l,mid),build(rc,mid+1,r);
    }
    void modify(int x,int l,int r,int ql,int qr,int v){
    	if(ql<=l and r<=qr) return put_tag(x,v);
    	push_down(x);
    	if(ql<=mid) modify(lc,l,mid,ql,qr,v);
    	if(qr>mid) modify(rc,mid+1,r,ql,qr,v);
    	tree[x]=tree[lc]+tree[rc];
    }
    node query(int x,int l,int r,int ql,int qr){
    	if(ql<=l and r<=qr) return tree[x];
    	push_down(x);
    	if(qr<=mid) return query(lc,l,mid,ql,qr);
    	if(ql>mid) return query(rc,mid+1,r,ql,qr);
    	return query(lc,l,mid,ql,qr)+query(rc,mid+1,r,ql,qr);
    }
    #undef lc
    #undef rc
    #undef mid
    
    int mx,px[N],py[N];
    vector<int> w[N];
    
    IN int f(int x){
    	return x==1 or x==3;
    }
    void solve(vector<int> a){
    	int x=a[0];
    	a.push_back(0),sort(a.begin(),a.end());
    	int p=lower_bound(a.begin(),a.end(),x)-a.begin();
    	for(int i=1;i<=p;++i){
    		int t=f(p-i+1)-f(p-i);
    		modify(1,1,mx,a[i-1]+1,a[i],t);
    	}
    }
    int main(){
    	int n=read<int>(),m=read<int>();
    	mx=n*m;
    	for(int i=0;i<=n+1;++i){
    		w[i].resize(m+2);
    		w[i][0]=w[i][m+1]=mx+1;
    		for(int j=1;j<=m;++j){
    			if(i==0 or i==n+1) w[i][j]=mx+1;
    			else read(w[i][j]),px[w[i][j]]=i,py[w[i][j]]=j;
    		}
    	}
    	build(1,1,mx);
    	int64 ans=0;
    	for(int i=1;i<=mx;++i){
    		int x=px[i],y=py[i];
    		solve({w[x][y],w[x-1][y],w[x][y-1],w[x-1][y-1]});
    		solve({w[x][y],w[x-1][y],w[x][y+1],w[x-1][y+1]});
    		solve({w[x][y],w[x+1][y],w[x][y-1],w[x+1][y-1]});
    		solve({w[x][y],w[x+1][y],w[x][y+1],w[x+1][y+1]});
    		node res=query(1,1,mx,1,i);
    		if(res.min==4) ans+=res.cnt;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    MySQL_01 常用命令
    32_Go基础(TCP通信)
    oracle查询优化
    Eclipse中自动添加注释(作者,时间)
    java注解的学习
    JqueryeasyUIdatagrid参数之 queryParams
    Eclipse中,打开文件所在文件夹的插件,及设置
    更改Zend Studio/Eclipse代码风格主题
    JAVA中使用File类批量重命名文件及java.io.File的常见用法
    java面试笔试题大全
  • 原文地址:https://www.cnblogs.com/autoint/p/13333803.html
Copyright © 2020-2023  润新知