您的位置:首页 > 其它

ZSOI2013 花瓶 分块

2016-03-23 15:28 134 查看
题意同上

分块大法好!

然而之前老师让我们做比赛的时候时写了300多行代码还没写对的我一脸懵逼= =

对于分块的不熟悉却又不想写线段树的我实际上是做大死= =

然后前天晚上真的只交了暴力上去

事后看了下别人的代码,发现郭隆写的分块比较优美,然后仿照他的代码又写了一次这道题

loc,BEGIN,END三个宏使我能直接开一个大数组了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i = a;i <= b; i++)
#define dfo(i,a,b) for(int i = a ;i >= b;i--)
using namespace std;
inline LL read()
{
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
#define N 50005
#define inf 10000000
#define M 300

#define loc(x) (1+(x)/sb)
#define BEGIN(x) (((x)-1)*sb)
#define END(x) (((x)*sb-1)<n?((x)*sb-1):n-1)

bool po
;
int sz[M],full[M],non[M],cur[M];
int n,m,sb,lb;

void pushlazy(int x)
{
if(non[x])
{
fo(i,BEGIN(x),END(x))po[i]=0;
non[x]=0;
}
if(full[x])
{
fo(i,BEGIN(x),END(x))po[i]=1;
full[x]=0;
}
}

void buildblocks()
{
for(sb=0;sb*sb<n;sb++);
lb=loc(n-1);
fo(i,1,lb)
{
sz[i]=END(i)-BEGIN(i)+1;
cur[i]=sz[i];
non[i]=full[i]=0;
}
}

void F(int beg,int f)
{
int fb=loc(beg),lv=0,zui=0;
bool flag1=0,flag2=0,flag=0;
int fp=-1,lp=-1;

//set the first block
pushlazy(fb);
fo(i,beg,END(fb))
if(!po[i])
{
po[i]=1;
cur[fb]--;
lp=i;
flag=1;
if(fp<0)
{
fp=i;
flag1=1;
}
if(--f==0)break;
}
if(f==0)
{
printf("%d %d\n",fp,lp);
return ;
}
//visit the blocks after
lv=fb;
fo(i,fb+1,lb)
if(cur[i])
{
if(fp<0)fp=i;
flag2=1;flag=1;
lp=i,lv=i;
if(f<=cur[i])
{
cur[i]-=f;
zui=f;
break;
}else
{
f-=cur[i];
zui=cur[i];
cur[i]=0;
full[i]=1;
}
}
if(!flag)
{
puts("Can not put any one.");
return ;
}
//if can't finish the first block we can visit in the first
//then seeking in the first block we visit
if(!flag1)
{
if(non[fp])fp=BEGIN(fp);
else
{
fo(i,BEGIN(fp),END(fp))
if(!po[i])
{
fp=i;
break;
}
}
}
//seeking in the last visit block
if(flag2)
{
//push the lazy label-non
if(non[lp])
{
fo(i,BEGIN(lp),END(lp))po[i]=0;
non[lp]=0;
}
//renew it
fo(i,BEGIN(lp),END(lp))
if(!po[i])
{
po[i]=1;
if(--zui==0)
{
lp=i;
break;
}
}

//renew the label-non
fo(i,fb+1,lv)non[i]=0;
}
printf("%d %d\n",fp,lp);
}

void R(int l,int r)
{
int fb=loc(l),lb=loc(r),ret=0;
pushlazy(fb);
if(fb==lb)
{
fo(i,l,r)
if(po[i])
{
po[i]=0;
ret++;
cur[fb]++;
}
}else
{
fo(i,l,END(fb))
if(po[i])
{
po[i]=0;
ret++;
cur[fb]++;
}
pushlazy(lb);
fo(i,BEGIN(lb),r)
if(po[i])
{
po[i]=0;
ret++;
cur[lb]++;
}
fo(i,fb+1,lb-1)
{
ret+=sz[i]-cur[i];
non[i]=1;
full[i]=0;
cur[i]=sz[i];
}
}
printf("%d\n",ret);
}

int main()
{
freopen("vase.in","r",stdin);
freopen("vase.out","w",stdout);
n=read(),m=read();
buildblocks();
fo(i,1,m)
{
int ccf=read();
if(ccf==1)
{
int a=read(),f=read();
F(a,f);
}else
{
int l=read(),r=read();
R(l,r);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  分块