HDU 5715 XOR 游戏(二分+dp+01字典树)

来源:互联网 发布:java 项目中使用log4j 编辑:程序博客网 时间:2024/06/06 19:01

nmL使
xmx
dp[i][k]=max(min(dp[j][k1],s[i]XORs[j]),dp[i][k])
0101s[i]x
s[j]01dp[j][k1]
m


代码

#include <map>#include <set>#include <ctime>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           10005#define   MAXN          1000005#define   maxnode       205#define   sigma_size    26#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-4;const LL    mod    = 772002;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/int sum[MAX];int ch[12][32*MAX][2];LL val[12][32*MAX];int num[12][32*MAX];int sz[12];int dp[MAX][12];int n,m,l;void init(){    for(int i=0;i<=m;i++){        mem(ch[i][0],0);        sz[i]=1;    }}void inser(LL a,int j){    int u=0;    for(int i=32;i>=0;i--){        int c=((a>>i)&1);        if(!ch[j][u][c]){            mem(ch[j][sz[j]],0);            val[j][sz[j]]=0;            num[j][sz[j]]=0;            ch[j][u][c]=sz[j]++;        }        u=ch[j][u][c];        num[j][u]++;    }    val[j][u]=a;}void del(LL a,int j){    int u=0;    for(int i=32;i>=0;i--){        int c=((a>>i)&1);        u=ch[j][u][c];        num[j][u]--;    }}LL query(LL a,int j){    int u=0;    for(int i=32;i>=0;i--){        int c=((a>>i)&1);        if(ch[j][u][c^1]&&num[j][ch[j][u][c^1]]) u=ch[j][u][c^1];        else if(ch[j][u][c]&&num[j][ch[j][u][c]]) u=ch[j][u][c];        else return -1;    }    return val[j][u]^a;}bool check(int x){    init();    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++) dp[i][j]=0;    }    inser(0,0);    dp[0][0]=1;    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            dp[i][j]=0;            if(i>l&&dp[i-l-1][j-1]) del(sum[i-l-1],j-1);        }        for(int j=m;j>0;j--){            LL a=query(sum[i],j-1);            if(a>=x){                inser(sum[i],j);                dp[i][j]=1;            }        }    }    return dp[n][m];}int main(){    //freopen("froggy.in","r",stdin);    //freopen("froggy.out","w",stdout);    int t,kase=0;    cin>>t;    while(t--){        kase++;        scanf("%d%d%d",&n,&m,&l);        sum[0]=0;        for(int i=1;i<=n;i++){            int a;            scanf("%d",&a);            sum[i]=sum[i-1]^a;        }        int l=0,r=2e9;        while(l<=r){            int mid=(l+r)/2;            if(check(mid)) l=mid+1;            else r=mid-1;        }        printf("Case #%d:\n%d\n",kase,r);    }    return 0;}
0 0
原创粉丝点击