首页 > 代码库 > 【codevs1191】数轴染色 序列分块
【codevs1191】数轴染色 序列分块
题目大意:
长度为n的序列,开始时全都是黑色的,m次操作,每次把[l,r]变成白色,求每次操作后剩下的黑点数。
分块直接做。
设rest[i]表示第i块剩下的个数,p为每个点的装填。
对于[l,r],找到l,r所处的块lblock,rblock。
把lblock+1到rblock-1的块的rest赋为0,O(√n)。
然后判断一下rest[lblock]是否空,如果不空则直接扫描更新rest和p,rblock同理。
注意这里要判断一下rest,因为整体赋值的时候p没有更新。
小结:对于分块,块数不能用unit+(unit*unit!=n),而要直接用(n-1)/unit+1。
#include <bits/stdc++.h> using namespace std; const int N=200010; const int S=500; int n,m,p[N]; int unit,num,rest[S],res; inline int Read(void) { int s=0,f=1; char c=getchar(); for (;!isdigit(c);c=getchar()) if (c==‘-‘) f=-1; for (;isdigit(c);c=getchar()) s=s*10+c-‘0‘; return s*f; } int main(void) { n=Read(); unit=(int)sqrt(n),num=(n-1)/unit+1; for (int i=1;i<=n;i++) p[i]=i; for (int i=1;i<num;i++) rest[i]=unit; rest[num]=n-(num-1)*unit; int l,r,lBlock,rBlock; m=Read(); for (int i=1;i<=m;i++) { l=Read(),r=Read(); lBlock=(l-1)/unit+1,rBlock=(r-1)/unit+1; if (lBlock==rBlock) if (rest[lBlock]) for (int i=l;i<=r;i++) if (p[i]) p[i]=0,rest[lBlock]--; else; else; else { for (int i=lBlock+1;i<=rBlock-1;i++) rest[i]=0; if (rest[lBlock]) for (int i=l;i<=lBlock*unit;i++) if (p[i]) p[i] =0,rest[lBlock]--; if (rest[rBlock]) for (int i=(rBlock-1)*unit+1;i<=r;i++) if (p[i]) p[i]=0,rest[rBlock]--; } res=0; for (int i=1;i<=num;i++) res+=rest[i]; printf("%d\n",res); } return 0; }
【codevs1191】数轴染色 序列分块
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。