时限为什么这么大啊

明摆着放多$ log$的做法过啊$QAQ$

LOJ #2013


题意

有$ Q$次询问,每次询问树上一条链,点有点权,你需要选择一些链上的点使得异或和尽量大

点数$ \leq 2*10^4$ 询问数$ \leq 2*10^5$ 值域不超过$ 2^{64}$


$ Solution$

直接点分

把询问用$ vector$挂在当前点分中心上

计算一个点的时候

递归计算它统率的子树,在每个点挂上从自己到根的线性基,

每次相当于继承父亲的线性基并插入一个数

然后将询问分成两类

不过当前点分中心的:下放到之后的点分计算

经过当前点分中心的:每次进行一次线性基合并然后求线性基最大值

总复杂度$ O(Q·60^2+n·60·log \ n)$


$My \ code$

#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define ull unsigned long long
#define M 40010
#define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)
#define rt register int
#define l putchar('\n')
#define ll long long
#define r read()
using namespace std;
inline ll read(){
ll x = ; char zf = ; char ch = getchar();
while (ch != '-' && !isdigit(ch)) ch = getchar();
if (ch == '-') zf = -, ch = getchar();
while (isdigit(ch)) x = x * + ch - '', ch = getchar(); return x * zf;
}
void write(ull y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ull y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt;ull ans[];
struct xxj{//线性基
#define sz 60
ull a[sz+];
xxj(){memset(a,,sizeof(a));}
void insert(ull x){
for(rt i=sz;x;i--)if(x>>i&){
if(!a[i])return a[i]=x,void();
x^=a[i];
}
}
bool check(const ull x){
for(rt i=sz;i>=;i--)if(x>>i&)if(!a[i])return ;
return ;
}
void rebuild(){
for(rt i=sz;i>=;i--)if(a[i])
for(rt j=i-;j>=;j--)if(a[j]>>i&)a[j]^=a[i];
}
ull Max(){
ull ret=;
for(rt i=sz;i>=;i--)if((ret^a[i])>ret)ret^=a[i];
return ret;
}
ull Min(){
for(rt i=;i<=sz;i++)if(a[i])return a[i];
return ;
}
ull kth(ull rk){
rebuild();ull ret=;
for(rt i=,j=;i<=sz;i++){
while(j<=sz&&!a[j])j++;
if(rk>>i&){
if(j>sz)return ;
ret^=a[j];
}j++;
}
return ret;
}
};
xxj merge(const xxj x,const xxj y){
xxj ret=y;
for(rt i=sz;i>=;i--)if(x.a[i])ret.insert(x.a[i]);
return ret;
}
#undef sz
struct query{
int x,y,id;
};
vector<query>ask[];
int nowmin,all,size[],Root,troot;
int F[M],L[M],N[M],a[M];ull v[M];bool vis[M];
void add(int x,int y){
a[++k]=y;
if(!F[x])F[x]=k;
else N[L[x]]=k;
L[x]=k;
}
void getroot(int x,int pre){
size[x]=;int maxsize=;
for(rt i=F[x];i;i=N[i])if(!vis[a[i]]&&a[i]!=pre){
getroot(a[i],x);
size[x]+=size[a[i]];
maxsize=max(maxsize,size[a[i]]);
}
maxsize=max(maxsize,all-size[x]);
if(maxsize<nowmin)nowmin=maxsize,Root=x;
}
int color[M];
void dfs_color(int x,int pre,int col){
color[x]=col;
for(rt i=F[x];i;i=N[i])if(a[i]!=pre&&!vis[a[i]])dfs_color(a[i],x,col);
}
xxj c[];
void dfs_calc(int x,int pre){
if(x==pre)memset(c[x].a,,sizeof(c[x].a));else c[x]=c[pre];
c[x].insert(v[x]);
for(rt i=F[x];i;i=N[i])if(a[i]!=pre&&!vis[a[i]])dfs_calc(a[i],x);
}
void calc(int x){
vis[x]=;color[x]=+x;
for(rt i=F[x];i;i=N[i])if(!vis[a[i]])dfs_color(a[i],x,a[i]);
dfs_calc(x,x);
for(auto i:ask[x]){
if(color[i.x]!=color[i.y])
ans[i.id]=max(ans[i.id],merge(c[i.x],c[i.y]).Max());
}
const int ls=all;
for(auto i:ask[x])if(color[i.x]==color[i.y])ask[color[i.x]+].push_back(i);
for(rt i=F[x];i;i=N[i])if(!vis[a[i]]){
if(size[a[i]]>size[x])all=nowmin=ls-size[x];else all=nowmin=size[a[i]];
getroot(a[i],x);ask[Root].clear();
ask[Root]=ask[a[i]+];ask[a[i]+].clear();
calc(Root);
}
}
int main(){
n=r;m=r;
for(rt i=;i<=n;i++)v[i]=r;
for(rt i=;i<n;i++){
x=r;y=r;
add(x,y);
add(y,x);
}
nowmin=all=n;getroot(,);troot=Root;
for(rt i=;i<=m;i++){
x=r;y=r;
if(x==y)ans[i]=v[x];else
ask[troot].push_back({x,y,i});
}
calc(troot);
for(rt i=;i<=m;i++)writeln(ans[i]);
return ;
}

LOJ #2013「SCOI2016」幸运数字的更多相关文章

  1. loj#2013. 「SCOI2016」幸运数字 点分治/线性基

    题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...

  2. loj #2013. 「SCOI2016」幸运数字

    #2013. 「SCOI2016」幸运数字 题目描述 A 国共有 n nn 座城市,这些城市由 n−1 n - 1n−1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以 ...

  3. 【LOJ】 #2013. 「SCOI2016」幸运数字

    题解 最大异或和,明显是个线性基 然而还有那么多路径--那就树分治,反正点数看起来很少,就是为了让人乘上一个60的常数嘛 把一个树的点分树记录下来,然后看看询问的两个点彼此相同的最后一个父亲是谁,把这 ...

  4. AC日记——「SCOI2016」幸运数字 LiBreOJ 2013

    「SCOI2016」幸运数字 思路: 线性基: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20005 # ...

  5. 「洛谷3292」「BZOJ4568」「SCOI2016」幸运数字【倍增LCA+线性基+合并】

    [bzoj数据下载地址]不要谢我 先讲一下窝是怎么错的... \(MLE\)是因为数组开小了.. 看到异或和最大,那么就会想到用线性基. 如果不会线性基的可以参考一下我的学习笔记:「线性基」学习笔记a ...

  6. loj2013 「SCOI2016」幸运数字

    点分治+线性基 (为了这六个字窝调了一下午一晚上QAQ #include <iostream> #include <cstring> #include <cstdio&g ...

  7. loj#2015. 「SCOI2016」妖怪 凸函数/三分

    题目链接 loj#2015. 「SCOI2016」妖怪 题解 对于每一项展开 的到\(atk+\frac{dnf}{b}a + dnf + \frac{atk}{a} b\) 令$T = \frac{ ...

  8. loj#2016. 「SCOI2016」美味

    题目链接 loj#2016. 「SCOI2016」美味 题解 对于不带x的怎么做....可持久化trie树 对于带x,和trie树一样贪心 对于答案的二进制位,从高往低位贪心, 二进制可以表示所有的数 ...

  9. loj#2012. 「SCOI2016」背单词

    题目链接 loj#2012. 「SCOI2016」背单词 题解 题面描述有点不清楚. 考虑贪心 type1的花费一定不会是优的,不考虑, 所以先把后缀填进去,对于反串建trie树, 先填父亲再填儿子, ...

随机推荐

  1. Could not install the app on the device, read the error above for details. Make sure you have an Android emulator running or a device connected and have set up your Android development environment:

    Administrator@DESKTOP-EHCTIOR MINGW64 /d/react-native-eyepetizer (master) $ react-native run-android ...

  2. 关于Nginx负载均衡的5种策略

    nginx的upstream目前支持的5种方式的分配 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. upstream backserver { ...

  3. cmd代码:查端口占用,查进程号,杀进程

    @echo off :main cls ::|findstr "8080" ::查找进程占用tasklist|findstr "XXXX" ::杀进程taskk ...

  4. Gym 101915

    Gym - 101915A  Printing Books 题意:有一本书,从第X页开始,一共用了n位数字,求此书一共多少页.99就是两位数字,100就是三位数字. 思路:直接模拟即可,我用了一个hi ...

  5. Luogu P2468 [SDOI2010]粟粟的书架

    一道二合一的题目.两部分思维难度都不太高,但是也都很巧妙.尤其是主席树的\(50\)分,由于本人初学主席树,所以没有见过主席树上二分的套路,就被小小的卡了一下.. \(n <= 200\) \( ...

  6. (LIS DP) codeVs 1044 拦截导弹

    题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...

  7. 绑定本地的Session

    绑定本地的Session图示解析: 代码的结构: 代码: SaveServlet.java package com.itheima.servlet; import java.io.IOExceptio ...

  8. 2017-12-15python全栈9期第二天第七节之运算符

    #!/user/bin/python# -*- coding:utf-8 -*-print(3>4 or 4<3 and 1==1)print(1<2 and 3 <4 or ...

  9. angular学习—组件

    组件: vue组件:xxx.vue react组件:xxx.js+xxx.css angular组件:xxx.ts+xxx.css+xxx.html angular的装饰器: @ngModule:an ...

  10. centos6.5mini版安装及配置

    1.安装选择界面,这个选第一个 2.镜像完整性检查,一般都是跳过SKIP 3.欢迎界面,进入安装了 4.语言选择,这个是没有中文的,用默认的英文就行 5.键盘布局,用默认的us 6.这里会给一个警告, ...