zoukankan      html  css  js  c++  java
  • 【线性基合并 树链剖分】bzoj4568: [Scoi2016]幸运数字

    板子题

    Description

    A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一。每座城市都有一个
    幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征。一些旅行者希望游览 A 国。旅行者计划
    乘飞机降落在 x 号城市,沿着 x 号城市到 y 号城市之间那条唯一的路径游览,最终从 y 城市起飞离开 A 国。
    在经过每一座城市时,游览者就会有机会与这座城市的幸运数字拍照,从而将这份幸运保存到自己身上。然而,幸
    运是不能简单叠加的,这一点游览者也十分清楚。他们迷信着幸运数字是以异或的方式保留在自己身上的。例如,
    游览者拍了 3 张照片,幸运值分别是 5,7,11,那么最终保留在自己身上的幸运值就是 9(5 xor 7 xor 11)。
    有些聪明的游览者发现,只要选择性地进行拍照,便能获得更大的幸运值。例如在上述三个幸运值中,只选择 5 
    和 11 ,可以保留的幸运值为 14 。现在,一些游览者找到了聪明的你,希望你帮他们计算出在他们的行程安排中
    可以保留的最大幸运值是多少。
     

    Input

    第一行包含 2 个正整数 n ,q,分别表示城市的数量和旅行者数量。第二行包含 n 个非负整数,其中第 i 个整
    数 Gi 表示 i 号城市的幸运值。随后 n-1 行,每行包含两个正整数 x ,y,表示 x 号城市和 y 号城市之间有一
    条道路相连。随后 q 行,每行包含两个正整数 x ,y,表示这名旅行者的旅行计划是从 x 号城市到 y 号城市。N
    <=20000,Q<=200000,Gi<=2^60
     

    Output

     输出需要包含 q 行,每行包含 1 个非负整数,表示这名旅行者可以保留的最大幸运值。


    题目分析

    树剖/倍增的板子题

    想用树剖来做一做,然而TLE了好几发。

    发现自己常数意识太差,每次query时候都开一个线性基,活生生浪费10s+

      1 #include<bits/stdc++.h>
      2 #define ENS //__attribute__((optimize("-O2")))
      3 #define NES //__attribute__((optimize("-O2"))) //__inline__ __attribute__((always_inline))
      4 typedef long long ll;
      5 const int maxn = 20035;
      6 const int maxm = 40035;
      7 const int maxq = 200035;
      8 
      9 struct Linear
     10 {
     11     ll p[103];
     12     Linear(){memset(p, 0, sizeof p);}
     13     NES void insert(ll c)
     14     {
     15         for (int i=60, chk=0; i>=0&&!chk; i--)
     16             if (c>>i){
     17                 if (p[i]) c ^= p[i];
     18                 else p[i] = c, chk = 1;
     19             }
     20     }
     21     NES void merge(Linear b)
     22     {
     23         for (int i=60; i>=0; i--)
     24             if (b.p[i]) insert(b.p[i]);
     25     }
     26     NES ll max()
     27     {
     28         ll ret = 0;
     29         for (int i=60; i>=0; i--)
     30             if ((ret^p[i]) > ret) ret ^= p[i];
     31         return ret;
     32     }
     33 }f[maxn<<2];
     34 struct node
     35 {
     36     int fa,son,top,tot;
     37 }a[maxn];
     38 int n,q,chain[maxn],chTot,dep[maxn];
     39 int edgeTot,head[maxn],nxt[maxm],edges[maxm];
     40 ll g[maxn],cnVal[maxn];
     41 
     42 template <typename T> NES void read(T&x)
     43 {
     44     char cu=getchar();x=0;bool fla=0;
     45     while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}
     46     while(isdigit(cu))x=x*10+cu-'0',cu=getchar();
     47     if(fla)x=-x; 
     48 }
     49 void write(ll x){if (x/10) write(x/10);putchar('0'+x%10);}
     50 void writeln(ll x){write(x), putchar('
    ');}
     51 NES void addedge()
     52 {
     53     int u,v;
     54     read(u), read(v);
     55     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
     56     edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
     57 }
     58 void dfs1(int x, int fa)
     59 {
     60     a[x].son = a[x].top = -1, a[x].fa = fa; 
     61     a[x].tot = 1, dep[x] = dep[fa]+1;
     62     for (int i=head[x]; i!=-1; i=nxt[i])
     63     {
     64         int v = edges[i];
     65         if (v!=fa){
     66             dfs1(v, x), a[x].tot += a[v].tot;
     67             if (a[x].son==-1||a[a[x].son].tot < a[v].tot) a[x].son = v;
     68         }
     69     }
     70 }
     71 void dfs2(int x, int top)
     72 {
     73     a[x].top = top, chain[x] = ++chTot, cnVal[chTot] = g[x];
     74     if (a[x].son==-1) return;
     75     dfs2(a[x].son, top);
     76     for (int i=head[x]; i!=-1; i=nxt[i])
     77     {
     78         int v = edges[i];
     79         if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
     80     }
     81 }
     82 void build(int rt, int l, int r)
     83 {
     84     if (l==r){
     85         f[rt].insert(cnVal[l]);
     86         return;
     87     }
     88     int mid = (l+r)>>1;
     89     build(rt<<1, l, mid);
     90     build(rt<<1|1, mid+1, r);
     91     f[rt] = f[rt<<1], f[rt].merge(f[rt<<1|1]);
     92 }
     93 Linear query(int rt, int l, int r, int L, int R)
     94 {
     95     if (L <= l&&r <= R) return f[rt];
     96     int mid = (l+r)>>1;
     97     if (L <= mid&&R > mid){
     98         
     99         Linear tmp = query(rt<<1, l, mid, L, R);
    100         tmp.merge(query(rt<<1|1, mid+1, r, L, R));
    101         return tmp;
    102     }else if (L <= mid) return query(rt<<1, l, mid, L, R);
    103     else if (R > mid) return query(rt<<1|1, mid+1, r, L, R);
    104 }
    105 NES void queryChain()
    106 {
    107     Linear ret;
    108     int x,y;
    109     read(x), read(y);
    110     while (a[x].top!=a[y].top)
    111     {
    112         if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
    113         ret.merge(query(1, 1, n, chain[a[y].top], chain[y]));
    114         y = a[a[y].top].fa;
    115     }
    116     if (dep[x] > dep[y]) std::swap(x, y);
    117     ret.merge(query(1, 1, n, chain[x], chain[y]));
    118     writeln(ret.max());
    119 }
    120 ENS int main()
    121 {
    122     memset(head, -1, sizeof head);
    123     read(n), read(q);
    124     for (int i=1; i<=n; i++) read(g[i]);
    125     for (int i=1; i<n; i++) addedge();
    126     dfs1(1, 0), dfs2(1, 1);
    127     build(1, 1, n);
    128     while (q--) queryChain();
    129     return 0;
    130 }

    END

  • 相关阅读:
    第0次作业 成绩统计
    助教第一次作业
    二进制协议 vs 文本协议
    Android TimeAnimator && TimeListener翻译
    Android 利用属ObjectAnimator,AnimatorSet性动画绘制一个弹球,加速下落,到底部时挤压,然后减速上弹
    Android使用属性动画ValueAnimator动态改变SurfaceView的背景颜色
    Android 绘制一个Loading动画__向图片中缓慢填充颜色,从而形成动画效果
    at android.view.Surface.unlockCanvasAndPost(Native Method)
    WebView之javascript与android交互基础加强
    WebView之加载网页时增加进度提示
  • 原文地址:https://www.cnblogs.com/antiquality/p/10195350.html
Copyright © 2011-2022 走看看