zoukankan      html  css  js  c++  java
  • codeforces840E In a Trap

    好巧妙啊,感觉从来没有用过按位dp的trick,也没有用过树上链分块的trick

    挂个,全程看他的思路写的,当然lych帮我理解了最难懂的一部分

    首先这里有个玄学的分块

    每个点统计它上面256(其实差不多就是n^0.5)个点的情况

    但是发现不同的块需要不同的处理,因为不同的块在第9位及以上的位会产生影响

    所以对于每个点都需要预处理出Fi,也就是当这个块是统计答案时的第i个块时的最大答案

    那么在跳的时候只要疯狂的跳256,同时记录下当前这一块已经是统计的第几块,最后不到256个暴力判一下

    然而

    暴力预处理是n*(256)^2≈n^2的

    gg

    于是可以用一个类似dp的方法做出来

    首先把每一个答案找一个最好的地方放好(就是块内的每一个点所对应的答案找一个i使答案的9~16位为11111111)

    接下来就一定是这些答案通过与下标同异或一个东西所得到的答案了

    先枚举位,考虑这些dp值在这一位取反对答案的贡献

    没了(感性理解是对的)

     1 #include <bits/stdc++.h>
     2 #define KUAI 256
     3 #define LOG 8
     4 #define FULL 255
     5 using namespace std;
     6 int n,m,E,x,y;
     7 int dep[50001],fa[50001],Fa[50001],ans[50001][300],a[50001],fir[50001],nex[100001],to[100001];
     8 void add(int x,int y)
     9 {
    10     nex[++E]=fir[x];fir[x]=E;to[E]=y;
    11 }
    12 void build(int now,int fat)
    13 {
    14     if(now==5)
    15         int e=1;
    16     dep[now]=dep[fat]+1;
    17     fa[now]=fat;
    18     for(int i=0,x=now;i<=KUAI && x;i++,x=fa[x])
    19     if(i==KUAI)
    20         Fa[now]=x;
    21     else
    22     {
    23         int y=a[x]^i;//当前答案 
    24         ans[now][FULL^(y>>LOG)]=max(ans[now][FULL^(y>>LOG)],y|(FULL<<LOG));//在最好的地方放好 
    25     } 
    26     for(int i=0;i<LOG;i++)
    27         for(int j=0;j<KUAI;j++)
    28             if(ans[now][j]==0)
    29             if(ans[now][j^(1<<i)])
    30                 ans[now][j]=ans[now][j^(1<<i)]^(1<<(LOG+i));
    31     for(int i=fir[now];i;i=nex[i])
    32     if(to[i]!=fa[now])
    33         build(to[i],now);
    34 }
    35 int main()
    36 {
    37     scanf("%d%d",&n,&m);
    38     for(int i=1;i<=n;i++)
    39         scanf("%d",&a[i]);
    40     for(int i=1;i<n;i++)
    41         scanf("%d%d",&x,&y),
    42         add(x,y),add(y,x);
    43     build(1,0);
    44     for(int i=1;i<=m;i++)
    45     {
    46         scanf("%d%d",&x,&y);
    47         if(i==2)
    48             int e=1;
    49         swap(x,y);
    50         int ret=a[y]^(dep[x]-dep[y]),j=0,de=0;
    51         for(;dep[x]-dep[y]>=KUAI;j++,de+=KUAI)
    52             ret=max(ret,ans[x][j]),x=Fa[x];
    53         for(;x!=y;x=fa[x],de++)
    54             ret=max(ret,a[x]^de);
    55         printf("%d
    ",ret);
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    POJ 2502 Subway(最短路径)
    HDU 1430 魔板
    HDU 1043 POJ 1077 八数码问题
    POJ 2576 Tug of War 随机算法(非正规解法)
    什么是COM
    6.0的版本的 tc,不支持大漠对象做数组吗?
    Q键连发。按住Q键则连发。松开则停止1。
    Q键连发。按住Q键 则连发。松开则停止2。
    特殊符号。
    僵尸_另类的生命体。
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7429683.html
Copyright © 2011-2022 走看看