• Xor && 线性基练习


     1 #include <cstdio>
     2 #include <cstring>
     3 const int Len=31;
     4 const int Maxn=100100;
     5 int cnt,Ans,b,x,n;
     6 inline int Max(int x,int y) {return x>y?x:y;}
     7 struct Node {int next[2];}Tree[Maxn*Len];
     8 void Insert(int x)
     9 {
    10     int Now=0; bool k;
    11     for (int i=Len;i>=0;i--)
    12     {
    13         k=x&(1<<i);
    14         if (Tree[Now].next[k]==-1) Tree[Now].next[k]=++cnt;
    15         Now=Tree[Now].next[k];
    16     }
    17 }
    18 int Query(int x)
    19 {
    20     int Now=0,v=0; bool k;
    21     for (int i=Len;i>=0;i--)
    22     {
    23         k=x&(1<<i);
    24         if (Tree[Now].next[!k]!=-1) k=!k;
    25         v=v|(k<<i);
    26         Now=Tree[Now].next[k];
    27     }
    28     return v;
    29 }
    30 int main()
    31 {
    32     // freopen("c.in","r",stdin);
    33     while (scanf("%d",&n)!=EOF)
    34     {
    35         Ans=cnt=0; memset(Tree,-1,sizeof(Tree));
    36         for (int i=1;i<=n;i++)
    37         {
    38             scanf("%d",&x);
    39             Insert(x);
    40             Ans=Max(Ans,x^Query(x));
    41         }
    42         printf("%d
    ",Ans);
    43     }
    44     return 0;
    45 }
    CSU1216

    在n个数取两个Xor最大。用0-1Trie.

     1 #include <cstdio>
     2 #include <algorithm>
     3 #define LL long long
     4 using namespace std;
     5 LL n,Ans,Base[1010];
     6 struct Node{LL a,b;}A[1010];
     7 inline bool cmp(Node A,Node B) {return A.b>B.b;}
     8  
     9 int main()
    10 {
    11     scanf("%lld",&n);
    12     for (LL i=1;i<=n;i++) scanf("%lld%lld",&A[i].a,&A[i].b);
    13     sort(A+1,A+n+1,cmp); Ans=0;
    14     for (LL i=1;i<=n;i++)
    15     {
    16         for (LL j=63;j>=0;j--)
    17             if (A[i].a>>j&1)
    18             {
    19                 if (!Base[j])
    20                 {
    21                     Base[j]=A[i].a;
    22                     break;
    23                 }
    24                 A[i].a^=Base[j];
    25             }
    26         if (A[i].a) Ans+=A[i].b;
    27     }
    28     printf("%lld
    ",Ans);
    29     return 0;
    30 }
    BZOJ2460

    若子集异或为0,则集合一定不为线性基。从大到小排序,贪心即可。

     1 #include <cstdio>
     2 #include <iostream>
     3 using namespace std;
     4 #define LL long long
     5 const LL Maxn=100100;
     6 LL a[Maxn],Kase,n,Ans,k,q,Bin[100];
     7 inline void Swap(LL &x,LL &y) {LL t=x;x=y;y=t;}
     8 inline LL Get(LL Row,LL k)
     9 {
    10     if (Row<n)
    11     {if (k==1) return 0; else k--;}
    12     if (k>=Bin[Row]) return -1;
    13     LL Ret=0;
    14     for (int i=1;i<=Row;i++)
    15         if (k&Bin[Row-i]) Ret^=a[i];
    16     return Ret;
    17 }
    18 int main()
    19 {
    20     scanf("%I64d",&Kase);
    21     Bin[0]=1; for (int i=1;i<=60;i++) Bin[i]=Bin[i-1]<<1;
    22     for (LL kase=1;kase<=Kase;kase++)
    23     {
    24         printf("Case #%I64d:
    ",kase);
    25         scanf("%I64d",&n);
    26         for (LL i=1;i<=n;i++) scanf("%I64d",&a[i]);
    27         LL Now=0;
    28         for (LL i=Bin[60];i;i>>=1)
    29         {
    30             LL j=Now+1;
    31             while (!(i&a[j])&&j<=n) j++;
    32             if (j==n+1) continue;
    33             ++Now; Swap(a[Now],a[j]);
    34             for (j=1;j<=n;j++)
    35             {
    36                 if (j==Now) continue;
    37                 if (a[j]&i) a[j]=a[j]^a[Now];
    38             }
    39         }        
    40         scanf("%I64d",&q);
    41         for (LL i=1;i<=q;i++)
    42         {
    43             scanf("%I64d",&k);
    44             printf("%I64d
    ",Get(Now,k));
    45         }
    46     }
    47     return 0;
    48 }
    HDU3949

    求第K大的Xor和,求出线性基,把K转为二进制在Xor就可以了

     1 #include <cstdio>
     2 #include <algorithm>
     3 #define LL long long
     4 using namespace std;
     5 const LL Mod=1000000009;
     6 const LL Maxn=1010;
     7 struct Node{LL b[Maxn],c;}a[Maxn];
     8 LL Base[Maxn],cnt,Ans,n,m;
     9 inline LL Pow(LL x,LL y)
    10 {
    11     LL Ret=1;
    12     while (true)
    13     {
    14         if (y&1) Ret=(Ret*x)%Mod;
    15         x=(x*x)%Mod; y>>=1; 
    16         if (y==0) break;
    17     }
    18     return Ret;
    19 }
    20 inline bool cmp(Node A,Node B) {return A.c<B.c;}
    21 int main()
    22 {
    23     scanf("%lld%lld",&n,&m);
    24     for (LL i=1;i<=n;i++)
    25         for (LL j=1;j<=m;j++) scanf("%lld",&a[i].b[j]);
    26     for (LL i=1;i<=n;i++) scanf("%lld",&a[i].c);
    27     sort(a+1,a+n+1,cmp);
    28     for (LL i=1;i<=n;i++)
    29     {
    30         bool flag=false;
    31         for (LL j=1;j<=m;j++)
    32             if (a[i].b[j])
    33             {
    34                 if (!Base[j])
    35                 {
    36                     Base[j]=i; flag=true;
    37                     break;
    38                 }
    39                 LL t=Mod-(a[i].b[j]*Pow(a[Base[j]].b[j],Mod-2))%Mod;
    40                 for (LL k=j;k<=m;k++)
    41                     a[i].b[k]=(a[i].b[k]+(t*a[Base[j]].b[k])%Mod)%Mod;
    42             }
    43         if (flag) Ans+=a[i].c,cnt++;
    44     }
    45     printf("%lld %lld
    ",cnt,Ans);
    46     return 0;
    47 }
    BZOJ4004

    即求出线性基,然后贪心取即可。

      1 #include <cstdio>
      2 #include <cstring>
      3 #define LL long long
      4 inline void Get_Int(LL & x)
      5 {
      6     char ch=getchar(); x=0;
      7     while (ch<'0' || ch>'9') ch=getchar();
      8     while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
      9 }
     10 inline void Swap(LL &x,LL &y) {LL t=x;x=y;y=t;}
     11 inline LL Max(LL x,LL y) {return x>y?x:y;}
     12 inline LL Min(LL x,LL y) {return x>y?y:x;}
     13 //==================================================
     14 const LL Maxn=20010;
     15 LL head[Maxn],father[Maxn][20],Dep[Maxn],n,m,Bin[70],x,u,v,cnt,Sum;
     16 bool vis[Maxn];
     17 struct Edge{LL to,next;}edge[Maxn<<2];
     18 struct Base
     19 {
     20     LL a[70];
     21     inline void Clr() {memset(a,0,sizeof(a));}
     22     inline void Insert(LL x) 
     23     {
     24         for (LL i=60;i>=0;i--)
     25             if (Bin[i]&x) 
     26             {
     27                 if (!a[i]) {a[i]=x; return;}
     28                 x^=a[i];
     29             }
     30     }
     31 }; 
     32 Base f[Maxn][20],Ans;
     33 inline void Add(LL u,LL v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;}
     34 void Dfs(LL u)
     35 {
     36     vis[u]=true;
     37     for (LL i=head[u];i!=-1;i=edge[i].next) 
     38         if (!vis[edge[i].to])
     39         {
     40             father[edge[i].to][0]=u;
     41             Dep[edge[i].to]=Dep[u]+1;
     42             Dfs(edge[i].to);
     43         }
     44 }
     45 inline void Init()
     46 {
     47     for (LL j=1;j<=15;j++)
     48         for (LL i=1;i<=n;i++)
     49         {
     50             father[i][j]=father[father[i][j-1]][j-1];
     51             for (LL k=60;k>=0;k--) if (f[i][j-1].a[k])f[i][j].Insert(f[i][j-1].a[k]);
     52             for (LL k=60;k>=0;k--) if (f[father[i][j-1]][j-1].a[k])f[i][j].Insert(f[father[i][j-1]][j-1].a[k]);
     53         }
     54 }
     55 void Solve(LL u,LL v)
     56 {
     57     if (Dep[u]<Dep[v]) Swap(u,v);
     58     for (LL i=15;i>=0;i--)
     59         if (Dep[father[u][i]]>=Dep[v])
     60         {
     61             for (LL k=60;k>=0;k--) if (f[u][i].a[k]) Ans.Insert(f[u][i].a[k]);
     62             u=father[u][i];
     63         }
     64     if (u==v) 
     65     {
     66         for (LL k=60;k>=0;k--) if (f[u][0].a[k]) Ans.Insert(f[u][0].a[k]);
     67         return;
     68     }
     69      
     70     for (LL i=15;i>=0;i--)
     71         if (father[u][i]!=father[v][i])
     72         {
     73             for (LL k=60;k>=0;k--) if (f[u][i].a[k]) Ans.Insert(f[u][i].a[k]);
     74             for (LL k=60;k>=0;k--) if (f[v][i].a[k]) Ans.Insert(f[v][i].a[k]);
     75             u=father[u][i],v=father[v][i];
     76         }
     77     for (LL k=60;k>=0;k--) if (f[u][0].a[k])Ans.Insert(f[u][0].a[k]);
     78     for (LL k=60;k>=0;k--) if (f[v][0].a[k])Ans.Insert(f[v][0].a[k]);
     79     for (LL k=60;k>=0;k--) if (f[father[u][0]][0].a[k])Ans.Insert(f[father[u][0]][0].a[k]);
     80 }
     81  
     82 int main()
     83 {
     84     Bin[0]=1; for (LL i=1;i<=60;i++) Bin[i]=Bin[i-1]<<1;
     85     Get_Int(n),Get_Int(m);
     86     for (LL i=1;i<=n;i++)
     87     {
     88         Get_Int(x);
     89         f[i][0].Insert(x);
     90     }
     91     memset(head,-1,sizeof(head));
     92     for (LL i=1;i<n;i++)
     93     {
     94         Get_Int(u),Get_Int(v);
     95         Add(u,v),Add(v,u);
     96     }
     97     father[1][0]=1; Dep[1]=1;
     98     memset(vis,false,sizeof(vis)); Dfs(1);
     99     Init();
    100     for (LL i=1;i<=m;i++)
    101     {
    102         Get_Int(u),Get_Int(v);
    103         Ans.Clr();
    104         Solve(u,v); Sum=0;
    105         for (LL j=60;j>=0;j--) Sum=Max(Sum,Sum^Ans.a[j]);
    106         printf("%lld
    ",Sum);
    107     }
    108     return 0;
    109 }
    BZOJ4568

    倍增合并线性基,贪心求最大值即可

  • 相关阅读:
    React路由基本的使用(一)
    Codeforces Round #627 (Div. 3) C
    Codeforces Round #627 (Div. 3) B
    Codeforces Round #627 (Div. 3) A
    hdu2049 不容易系列之(4)——考新郎(组合,错排)
    Codeforces Round #626 (Div. 2) E. Instant Noodles(二分图,最大公因数)
    Codeforces Round #626 (Div. 2) D. Present(位运算)
    逆元的计算方法
    Educational Codeforces Round 83 D. Count the Arrays(组合,逆元,快速幂)
    hdu4460 Friend Chains(记忆化广度优先搜索)
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5676589.html
Copyright © 2020-2023  润新知