• HDU5715 XOR 游戏 二分+字典树+dp


       当时Astar复赛的时候只做出1题,赛后补题(很长时间后才补,懒真是要命),发现这是第二简单的

       分析:

       这个题,可以每次二分区间的最小异或和

       进行check的时候用dp进行判断,dp[i][j]代表前i个元素分成j个区间,j是最后一个区间的最后一个元素

       如果dp[i][j]为真,表明每个区间长度大于L,异或和大于mid

       否则为假

       返回dp[n][m]就好

       复杂度度 O(30^2*nm)

      吐槽:和异或相关的题总是和字典树贪心有关,又是一道,铭记铭记

    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int N = 1e4+5;
    typedef long long LL;
    int n,m,l,T,cas,tot;
    int a[N];
    struct Node{
        int sum,nex[2];
    }p[N*35*12];
    int newnode(){
      ++tot;
      p[tot].sum=0;p[tot].nex[0]=p[tot].nex[1]=-1;
      return tot;
    }
    int root[12];
    void add(int pos,int x){
      int now=root[pos],cur;
      ++p[now].sum;
      for(int i=30;i>=0;--i){
        if(x&(1<<i))cur=1;
        else cur=0;
        if(p[now].nex[cur]==-1)
          p[now].nex[cur]=newnode();
        now=p[now].nex[cur];
        ++p[now].sum;
      }
    }
    void del(int pos,int x){
      int now=root[pos],cur; 
      --p[now].sum;
      for(int i=30;i>=0;--i){
         if(x&(1<<i))cur=1;
         else cur=0;
         now=p[now].nex[cur];
          --p[now].sum;
      }
    }
    int query(int pos,int x){
      int now=root[pos],ret=0,cur;
      if(p[now].sum==0)return 0;
      for(int i=30;i>=0;--i){
         if(x&(1<<i))cur=1;
         else cur=0;
         if(p[now].nex[cur^1]!=-1&&p[p[now].nex[cur^1]].sum!=0){
            ret+=(1<<i);
            now=p[now].nex[cur^1];
         }
         else now=p[now].nex[cur];
      }
      return ret;
    }
    bool dp[N][12];
    bool check(int mid){
      tot=0;
      for(int i=0;i<m;++i)
        root[i]=newnode();
      for(int i=0;i<=n;++i)
        for(int j=0;j<=m;++j)dp[i][j]=false;
      dp[0][0]=true;add(0,0);
      for(int i=1;i<=n;++i){
        if(i-l-1>=0){
          for(int j=0;j<=m;++j)
             if(dp[i-l-1][j])del(j,a[i-l-1]);
        }
        for(int j=1;j<=m;++j){
          int tmp=query(j-1,a[i]);
          if(tmp>=mid)add(j,a[i]),dp[i][j]=true;
        }   
      }
    
      return dp[n][m];
    }
    int main(){
      scanf("%d",&T);
      while(T--){
        scanf("%d%d%d",&n,&m,&l);
        for(int i=1;i<=n;++i)
          scanf("%d",&a[i]),a[i]^=a[i-1];
        int l=0,r=1e9+7,ret;
        while(l<=r){
          int mid=(l+r)>>1;
          if(check(mid))l=mid+1,ret=mid;
          else r=mid-1;
        }
        printf("Case #%d:
    %d
    ",++cas,ret);
      }
      return 0;
    }
    View Code
  • 相关阅读:
    (三)对极几何
    Pythonista中文教程
    Pythonista中文文档
    资源:《C语言程序设计(第五版)谭浩强》及《C语言程序设计:学习辅导(第五版)谭浩强》PDF下载
    重庆邮电大学2020计算机专硕375分经验分享
    LeetCode题目汇总
    CCF-CSP题目汇总
    CCF-CSP:201909-3字符画
    CCF-CSP:201909-2小明种苹果(续)
    CCF-CSP:201909-1小明种苹果
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5636012.html
Copyright © 2020-2023  润新知