扫描线
又到了noip的时节,
我想起了扫描线。
以前也只做过一道题。
我试着裸打一个扫描线,pku 的 atlantis。
附上另一道我几乎是直接抄的程序,虽然没有交(只过了编译),但是实在抱歉。。
//复健用 仅为纪念 #include<cmath> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define ll long long #define M 2001 int read(){ int x=0,fh=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*fh; } int N,A,B,g[M]; bool f[M][M]; ll s[M],ans=0; bool check(ll sum,ll ans,int bit){ return (sum>>(bit+1)|ans==ans)&&(((sum>>bit)&1)==0); } void work1(){ for(int i=(int)log2(s[N]);i>=0;i--){ memset(f,0,sizeof(f)); f[0][0]=true; for(int j=1;j<=N;j++){ for(int k=1;k<=min(j,B);k++){ f[j][k]=false; for(int l=1;l<=j&&!f[j][k];l++) f[j][k]|=(f[l-1][k-1])&&(check(s[j]-s[l-1],ans,i)); } } bool b=false; for(int i=A;i<=B&&!b;i++){ b|=f[N][i]; } ans=ans<<1|!b; } } void work2(){ for(int i=(int)log2(s[N]);i>=0;i--){ g[0]=0; for(int j=1;j<=N;j++){ g[j]=B+1; for(int k=1;k<=j;k++) if(g[k-1]+1<g[j]&&check(s[j]-s[k-1],ans,i)) g[j]=g[k-1]+1; } ans=(ans<<1)|(g[N]>B); } } int main() { freopen("inp.in","r",stdin); N=read();A=read();B=read();s[0]=0; for(int i=1;i<=N;i++){ int x=read(); s[i]=s[i-1]+(ll)x; } if(A>1)work1(); else work2(); printf("%I64d",ans); }
————————————————————————————————
お前の明日が今日よりもずっと楽しいことで溢れてるようにと、祈ってる
posted on 2016-09-09 21:38 Crisscross 阅读(184) 评论(0) 编辑 收藏 举报