Ural1540 Battle for the Ring

来源:互联网 发布:备孕前准备 知乎 编辑:程序博客网 时间:2024/06/05 04:12

区间DP+SG函数

看到代码淦过去的时候我的内心是崩溃的…
明明O(n^4)啊。。

#include<cstdio>#include<iostream>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>using namespace std;char c;inline void read(int&a){    a=0;do c=getchar();while(c<'0'||c>'9');    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}const    int M=15,N=(1<<M)-1,C=30;int Low[1<<M];int Val[C+1];struct Rec{    int Len;    int R[13];    void clear(){Len=0;memset(R,0,sizeof(R));}    Rec(){Len=0;memset(R,0,sizeof(R));}    Rec(int L){Len=L/C+1;memset(R,0,sizeof(R));}    void Unclear()    {        for(int i=0;i<7;i++)R[i]=(N<<15)|N;    }    void Cg(int no,int da)    {        int W=no/C;        int D=no%C;        if(!da)            R[W]=(R[W]|Val[D])^Val[D];        else R[W]=(R[W]|Val[D]);    }    int ck(int no)    {        int W=no/C;        int D=no%C;        return R[W]&Val[D];    }    int LowBit()    {        for(int i=0;i<Len;i++)            if(Low[R[i]&N])                return Low[R[i]&N]+i*C;            else if(Low[R[i]>>M])                return Low[R[i]&N]+i*C+M;        return 0;    }};struct Chain{    int n;    int V[101];    int Sol[101][101];    int F(int x,int y)    {        if(y<x)return 0;        int &A=Sol[x][y];        Rec SG;        SG.Len=302;        SG.Unclear();        if(A)return A;        for(int i=x;i<=y;i++)        {            int l=x,tp=0;            for(int j=x;j<=y;j++)                if(V[j]<=V[i])                    tp^=F(l,j-1),l=j+1;            tp^=F(l,y);            SG.Cg(tp,0);            }        int i;        for(i=0;!SG.ck(i);i++);A=i;  //  printf("%d %d %d\n",x,y,A);        return A;    }    int get()    {        read(n);        for(int i=1;i<=n;i++)read(V[i]);        return F(1,n);      }    int A(int S)    {        S^=Sol[1][n];        Rec SG(302);        for(int i=1;i<=n;i++)        {            int l=1,tp=0;            for(int j=1;j<=n;j++)                if(V[j]<=V[i])                    tp^=F(l,j-1),l=j+1;            tp^=F(l,n);            if(tp==S)                return i;        }        return SG.LowBit();    }}L[51];int main(){    Val[0]=1;    for(int i=1;i<=14;i++)Low[Val[i]=Val[i-1]<<1]=i;    for(int i=14;i<=30;i++)Val[i]=Val[i-1]<<1;    for(int i=1;i<=N;i++)Low[i]=Low[i&-i];    int n,T=0,tt;    read(n);    for(int i=1;i<=n;i++)T^=(tt=L[i].get());    if(!T){puts("S");return 0;}    puts("G");    for(int i=1;i<=n;i++)    {        int t=L[i].A(T);        if(t){printf("%d %d\n",i,t);return 0;}    }    return 0;}
0 0
原创粉丝点击