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\n",ret);
56     }
57     return 0;
58 }
时间: 2024-10-25 12:19:40

codeforces840E In a Trap的相关文章

uva 1318 - Monster Trap(bfs+暴力)

题目链接:uva 1318 - Monster Trap 每条线段2个点,加上起点终点一个是202个点,暴力判断连点之间是否可达,可达建边.因为线段有厚度考虑,所以将线段延伸一点再处理,这样原本共用一端点的线段变成相交.特殊情况是三点共线,这是判断延伸后的点是否落在其他线段上,如果是就不考虑这个点.最后做一遍bfs. #include <cstdio> #include <cstring> #include <cmath> #include <vector>

bash脚本技巧-trap命令

分享一个shell脚本技巧,大家写shell脚本的时候,一般而言仅仅保证功能可用,但程序的鲁棒性却不是太好,不够健壮,多数是脚本处理 一些中断信号导致,应对非预期的系统信号,其实系统自带的trap命令可以很好的处理,例如: trap "rm -f /var/lock/subsys/my_program_lock_file; exit 0" 1 2 9 15 上面的意思简单讲,就是捕获到信号1,2,9,15的时候执行引号里面的脚本(删除锁文件,并退出) 另外具体的系统信号是什么,可以通过

Erlang ERTS的Trap机制的设计及其用途

出处:http://mryufeng.iteye.com/blog/334744 erlang的trap机制在实现中用的很多,在费时的BIF操作中基本上都可以看到.它的实现需要erl vm的配合.它的作用基本上有3个: 1. 把费时操作分阶段做.由于erlang是个软实时系统,一个进程或者bif不能无限制的占用cpu时间.所以erlang的每个进程执行的时候,最多只能执行一定数量的指令.这个是设计方面的目标.实现上也要配套.所以比如md5,list_member查找这种可能耗时的操作都是用tra

Linux trap(捕捉) 命令

trap 命令用于指定在接收到信号后将要采取的行动: trap 命令的参数分为两部分,前一部分是接收到指定信号时将要采取的行动,后一部分是要处理的信号名.而且必须在你想保护的那部分代码以前指定trap命令. 格式:trap commands signal-list 例如:trap "cp -f /etc/resolv.conf.bak /etc/resolv.conf;exit"  INT .......................................... 信 号(S

trap命令

重要的一些信号 1)SIGHUP本信号在用户终端连接结束时发出                    挂起,通常由终端掉线或用户退出而引发2)SIGINT程序终止信号,在用户键入Ctrl-C时发出                中断,通常因按下Ctrl+C而引发3)SIGQUIT和信号2类似,由Ctrl-/来控制,进程收到SIGQUIT会产生core文件    退出,通常因按下Ctrl+/而引发6)SIGABRT程序自己发现错误并调用abort时产生                中止,通常因某

shell中trap捕捉到信号的处理

一. trap捕捉到信号之后,可以有三种反应方式: (1)执行一段程序来处理这一信号 (2)接受信号的默认操作 (3)忽视这一信号 二. trap对上面三种方式提供了三种基本形式: 第一种形式的trap命令在shell接收到signal list清单中数值相同的信号时,将执行双 引号中的命令串. trap 'commands' signal-list trap "commands" signal-list 为了恢复信号的默认操作,使用第二种形式的trap命令: trap signal-

#每日Linux小练习#09 trap指令

在有些情况下,我们不希望自己的shell脚本在运行时刻被中断,比如说我们写得shell脚本设为某一用户的默认shell,使这一用户进入系统后只能作某一项工作,如数据库备份, 我们可不希望用户使用ctrl+C之类便进入到shell状态,做我们不希望做的事情.这便用到了信号处理. trap命令用来指定shell需要捕捉哪些Linux信号,以及如何处理这些信号.格式如下: trap commands signals 不同的signal之间用空格隔开,commands表示如何处理signals. ech

中断(interrupt)、异常(exception)、陷入(trap)

http://blog.chinaunix.net/cp.php?ac=blog 中断:是为了设备与CPU之间的通信.典型的有如服务请求,任务完成提醒等.比如我们熟知的时钟中断,硬盘读写服务请求中断.中断的发生与系统处在用户态还是在内核态无关,只决定于EFLAGS寄存器的一个标志位.我们熟悉的sti, cli两条指令就是用来设置这个标志位,然后决定是否允许中断.在单个CPU的系统中,这也是保护临界区的一种简便方法.中断是异步的,因为从逻辑上来说,中断的产生与当前正在执行的进程无关.事实上,中断是

bash - trap

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html The syntax for the trap statement is straightforward: trap [COMMANDS] [SIGNALS]