这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
|
2020-2021:teams:legal_string:组队训练比赛记录:contest9 [2021/08/01 19:18] jxm2001 |
2020-2021:teams:legal_string:组队训练比赛记录:contest9 [2021/08/06 21:07] (当前版本) jxm2001 |
||
|---|---|---|---|
| 行 5: | 行 5: | ||
| ^ 题目 ^ 蒋贤蒙 ^ 王赵安 ^ 王智彪 ^ | ^ 题目 ^ 蒋贤蒙 ^ 王赵安 ^ 王智彪 ^ | ||
| | A | 0 | 0 | 0 | | | A | 0 | 0 | 0 | | ||
| - | | C | 2 | 0 | 0 | | + | | C | 2 | 1 | 0 | |
| - | | E | 0 | 0 | 0 | | + | | E | 2 | 0 | 1 | |
| - | | F | 0 | 0 | 2 | | + | | F | 0 | 1 | 2 | |
| | G | 2 | 0 | 2 | | | G | 2 | 0 | 2 | | ||
| - | | I | 2 | 0 | 0 | | + | | I | 2 | 1 | 0 | |
| - | | J | 2 | 0 | 1 | | + | | J | 2 | 1 | 1 | |
| ====== 题解 ====== | ====== 题解 ====== | ||
| 行 101: | 行 101: | ||
| ans=(ans+1LL*solve(n,i)*quick_pow(n+1,i-1))%mod; | ans=(ans+1LL*solve(n,i)*quick_pow(n+1,i-1))%mod; | ||
| enter(ans); | enter(ans); | ||
| + | return 0; | ||
| + | } | ||
| + | </code> | ||
| + | </hidden> | ||
| + | |||
| + | ===== E. Eert Esiwtib ===== | ||
| + | |||
| + | ==== 题意 ==== | ||
| + | |||
| + | 给定一棵以 $1$ 为根的点权树,记第 $i$ 个点的原始点权为 $a_i$。每条边有一种操作符,可能为 $\text{OR},\text{AND},\text{XOR}$。 | ||
| + | |||
| + | 设路径 $u\to v$ 上的点权和操作符依次为 $p_1,e_1,p_2\cdots e_{k-1},p_k$,则路径的权重 $w(u,v)=p_1 e_1(p_2 e_2(\cdots (p_{k-2}e_{k-2}(p_{k-1}e_{k-1}p_k))\cdots))$。 | ||
| + | |||
| + | 定义 $\text{Tree}(u)$ 表示 $u$ 的子树,不包括 $u$ 本身。接下来若干询问,每次给定 $d,u$,将每个点的点权变为 $a_i+d\times i$,求 | ||
| + | |||
| + | $$ | ||
| + | \text{OR}_{v\in Tree(u)}w(u,v),\text{AND}_{v\in Tree(u)}w(u,v),\text{XOR}_{v\in Tree(u)}w(u,v) | ||
| + | $$ | ||
| + | |||
| + | 注意,每组询问对点权的修改独立,即一个询问对点权的修改不影响另一个询问。同时有 $0\le d\le 100$。 | ||
| + | |||
| + | ==== 题解 ==== | ||
| + | |||
| + | 发现 $d$ 很小,直接枚举 $d$,暴力树形 $\text{dp}$ 即可。设 $\text{dp}(u,0/1/2)$ 表示 $u$ 求 $\text{OR},\text{AND},\text{XOR}$ 情况下的答案,大力分类讨论即可。 | ||
| + | |||
| + | 注意权值直接运算时每个位是独立的,所以在讨论时可以只考虑权值是 $0/1$ 的情况,然后枚举 $u$ 是 $0,1$ 考虑一下即可。 | ||
| + | |||
| + | 例如,考虑边是 $\text{XOR}$ 的情况,计算下式 | ||
| + | |||
| + | $$ | ||
| + | (a_u\oplus v_1)|(a_u\oplus v_2)|\cdots (a_u\oplus v_k) | ||
| + | $$ | ||
| + | |||
| + | 首先假设 $a_u=0$,得到 $(a_u\oplus v_1)|(a_u\oplus v_2)|\cdots |(a_u\oplus v_k)=v_1|v_2|\cdots |v_k=\text{dp}(v,0)$。 | ||
| + | |||
| + | 假设 $a_u=1$,得到 $(a_u\oplus v_1)|(a_u\oplus v_2)|\cdots |(a_u\oplus v_k)=(\sim v_1)|(\sim v_2)|\cdots |(\sim v_k)=\sim (v_1\And v_2\And \cdots \And v_k)=\sim \text{dp}(v,1)$。 | ||
| + | |||
| + | 于是有 $\text{dp}(u,0)|=((\sim a_u)\And \text{dp}(v,0))|(a_u\And (\sim \text{dp}(v,1)))$。注意 $\text{dp}(v)$ 不包含 $v$ 本身的贡献所以还有 $\text{dp}(u,0)|=a_u|a_v$。 | ||
| + | |||
| + | 总时间复杂度 $O(nd)$。 | ||
| + | |||
| + | |||
| + | <hidden 查看代码> | ||
| + | <code cpp> | ||
| + | const int MAXN=1e5+5,MAXV=105; | ||
| + | struct Edge{ | ||
| + | int to,w,next; | ||
| + | }edge[MAXN]; | ||
| + | int head[MAXN],edge_cnt; | ||
| + | void Insert(int u,int v,int w){ | ||
| + | edge[++edge_cnt]=Edge{v,w,head[u]}; | ||
| + | head[u]=edge_cnt; | ||
| + | } | ||
| + | LL a0[MAXN],a[MAXN],dp[MAXN][3]; | ||
| + | int sz[MAXN]; | ||
| + | void dfs(int u){ | ||
| + | dp[u][0]=dp[u][2]=0; | ||
| + | dp[u][1]=-1; | ||
| + | sz[u]=1; | ||
| + | for(int i=head[u];i;i=edge[i].next){ | ||
| + | int v=edge[i].to; | ||
| + | dfs(v); | ||
| + | sz[u]+=sz[v]; | ||
| + | LL t; | ||
| + | if(edge[i].w==0)t=a[u]|a[v]; | ||
| + | else if(edge[i].w==1)t=a[u]&a[v]; | ||
| + | else t=a[u]^a[v]; | ||
| + | dp[u][0]|=t; | ||
| + | dp[u][1]&=t; | ||
| + | dp[u][2]^=t; | ||
| + | if(sz[v]==1)continue; | ||
| + | sz[v]--; | ||
| + | if(edge[i].w==0){ | ||
| + | dp[u][0]|=a[u]|dp[v][0]; | ||
| + | dp[u][1]&=a[u]|dp[v][1]; | ||
| + | if(sz[v]&1) | ||
| + | dp[u][2]^=a[u]|((~a[u])&dp[v][2]); | ||
| + | else | ||
| + | dp[u][2]^=(~a[u])&dp[v][2]; | ||
| + | } | ||
| + | else if(edge[i].w==1){ | ||
| + | dp[u][0]|=a[u]&dp[v][0]; | ||
| + | dp[u][1]&=a[u]&dp[v][1]; | ||
| + | dp[u][2]^=a[u]&dp[v][2]; | ||
| + | } | ||
| + | else{ | ||
| + | dp[u][0]|=(a[u]&(~dp[v][1]))|((~a[u])&dp[v][0]); | ||
| + | dp[u][1]&=(a[u]&(~dp[v][0]))|((~a[u])&dp[v][1]); | ||
| + | if(sz[v]&1) | ||
| + | dp[u][2]^=a[u]^dp[v][2]; | ||
| + | else | ||
| + | dp[u][2]^=dp[v][2]; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | vector<pair<int,int> > c[MAXV]; | ||
| + | LL ans[MAXN][3]; | ||
| + | int main(){ | ||
| + | int n=read_int(),q=read_int(); | ||
| + | _rep(i,1,n) | ||
| + | a0[i]=read_int(); | ||
| + | _rep(i,2,n){ | ||
| + | int f=read_int(),s=read_int(); | ||
| + | Insert(f,i,s); | ||
| + | } | ||
| + | _for(i,0,q){ | ||
| + | int d=read_int(),u=read_int(); | ||
| + | c[d].push_back(make_pair(i,u)); | ||
| + | } | ||
| + | _for(d,0,MAXV){ | ||
| + | _rep(i,1,n) | ||
| + | a[i]=a0[i]+i*d; | ||
| + | dfs(1); | ||
| + | for(pair<int,int> t:c[d]){ | ||
| + | _for(j,0,3) | ||
| + | ans[t.first][j]=dp[t.second][j]; | ||
| + | } | ||
| + | } | ||
| + | _for(i,0,q){ | ||
| + | space(ans[i][0]); | ||
| + | space(ans[i][1]); | ||
| + | enter(ans[i][2]); | ||
| + | } | ||
| return 0; | return 0; | ||
| } | } | ||
| 行 404: | 行 527: | ||
| int main() | int main() | ||
| { | { | ||
| - | // freopen("test.in","r",stdin); | ||
| int n=read_int(),q=read_int(); | int n=read_int(),q=read_int(); | ||
| _rep(i,1,n) | _rep(i,1,n) | ||