题意同上
分块大法好!
然而之前老师让我们做比赛的时候时写了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[N]; 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; }