zoukankan      html  css  js  c++  java
  • [luogu3292]幸运数字

    考虑点分治,将询问离线后计算重心到每一个点的线性基,然后再询问重心到每一个点的线性基,时间复杂度为$o(3600q)$,可以过(然而太菜的我写了倍增维护线性基,震惊于倍增和线性基常数之小)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 20005
     4 #define oo 0x3f3f3f3f
     5 #define ll long long
     6 struct ji{
     7     ll a[61];
     8 }o,dp[N][21];
     9 struct ji2{
    10     int nex,to;
    11 }edge[N<<1];
    12 int E,n,m,x,y,head[N],in[N],out[N],f[N][21];
    13 ll a[N];
    14 bool pd(int x,int y){
    15     return (in[x]<=in[y])&&(out[y]<=out[x]);
    16 }
    17 void add(int x,int y){
    18     edge[E].nex=head[x];
    19     edge[E].to=y;
    20     head[x]=E++;
    21 }
    22 void add(ji &x,ll y){
    23     for(int i=60;i>=0;i--)
    24         if (y&(1LL<<i))
    25             if (x.a[i])y^=x.a[i];
    26             else{
    27                 x.a[i]=y;
    28                 break;
    29             }
    30 }
    31 void merge(ji &x,ji y){
    32     for(int i=0;i<=60;i++)
    33         if (y.a[i])add(x,y.a[i]);
    34 }
    35 void dfs(int k,int fa){
    36     in[k]=++x;
    37     f[k][0]=fa;
    38     add(dp[k][0],a[k]);
    39     for(int i=1;i<=20;i++){
    40         f[k][i]=f[f[k][i-1]][i-1]; 
    41         dp[k][i]=dp[k][i-1];
    42         merge(dp[k][i],dp[f[k][i-1]][i-1]);
    43     }
    44     for(int i=head[k];i!=-1;i=edge[i].nex)
    45         if (edge[i].to!=fa)dfs(edge[i].to,k);
    46     out[k]=++x;
    47 }
    48 ji calc(int x,int y){
    49     if (x==y)return dp[x][0];
    50     ji z;
    51     memset(z.a,0,sizeof(z.a));
    52     for(int i=20;i>=0;i--)
    53         if (!pd(f[x][i],y)){
    54             merge(z,dp[x][i]);
    55             x=f[x][i];
    56         }
    57     for(int i=20;i>=0;i--)
    58         if (!pd(f[y][i],x)){
    59             merge(z,dp[y][i]);
    60             y=f[y][i];
    61         }
    62     merge(z,dp[x][pd(x,y)^1]);
    63     if (!pd(y,x))merge(z,dp[y][0]);
    64     return z;
    65 }
    66 ll query(ji o){
    67     ll ans=0;
    68     for(int j=60;j>=0;j--)
    69         if ((ans&(1LL<<j))==0)ans^=o.a[j];
    70     return ans;
    71 }
    72 int main(){
    73     scanf("%d%d",&n,&m);
    74     memset(head,-1,sizeof(head));
    75     for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    76     for(int i=1;i<n;i++){
    77         scanf("%d%d",&x,&y);
    78         add(x,y);
    79         add(y,x);
    80     }
    81     dfs(1,1);
    82     for(int i=1;i<=m;i++){
    83         scanf("%d%d",&x,&y);
    84         printf("%lld\n",query(calc(x,y)));
    85     }
    86 }
    View Code
  • 相关阅读:
    CentOS7 64位下MySQL5.7安装与配置
    Linux CentOS7.0下JAVA安装和配置环境变量
    在MySQL中使用explain查询SQL的执行计划
    ionic3中使用自定义配置
    RabbitMQ发布订阅实战-实现延时重试队列
    springboot 项目mybatis plus 设置 jdbcTypeForNull (oracle数据库需配置JdbcType.NULL, 默认是Other)
    Python之Mysql及SQLAlchemy操作总结
    数据库分库分表思路
    RPC框架实践之:Apache Thrift
    vue使用watch 观察路由变化,重新获取内容
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11330369.html
Copyright © 2011-2022 走看看