[JZOJ5984] 仙人掌
Description
Solution
标算我并不会...
考虑一种根号思想
首先以 \(1\) 为根dfs整棵树
那么在任意时刻一个点的儿子的权值种类最多只会有 \(\sqrt m\) 种。
可以在每个点维护一个邻接表,存储这个点的儿子们的所有权值种类,以及该权值出现次数。
考虑如何支持修改
如果要对点 \(x\) 进行修改
首先要改它的父亲 \(fa\),就要找到它父亲的父亲 \(y\) ,因为 \(fa\) 是 \(y\) 的儿子,\(fa\) 的信息储存在了 \(y\) 邻接表里。
具体是在 \(y\) 的邻接表中找到 \(fa\) 当前的权值 \(val\),然后把这个点的出现次数 \(-1\)。再把 \(val+1\) 的出现次数 \(+1\)。这样就完成了对 \(fa\) 权值的修改。
然后改点 \(x\) 的所有儿子就比较方便了,直接遍历 \(x\) 的邻接表,把所有点的权值 \(+1\) 就好了。
看上去就做完了,但是我们还不能支持查询任意一个点当前的权值。因为邻接表存的是一个个"等价类",是无法区分具体的点的。
所以我们还需要在每个点维护两个标记方便我们快速知道真正的点权,具体是维护 \(tag[i],tag2[i]\) 分别表示修改过点 \(i\) 的儿子们多少次和点 \(i\) 的儿子们修改过多少次。这样 \(tag[i]+tag2[i]\) 就是点 \(i\) 的真实权值了。
时间复杂度 \(O(m\sqrt m)\) 但远远达不到上界。
还跑了个rank1
Code
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
const int N=5e5+5;
const ll mod=1000109107;
ll tot=0;
int tag[N],tag2[N];
int n,m,son[N],fa[N];
struct Edge{
int to,nxt,sze;
};
struct G{
int dp[N],dc;
int head[N],cnt;
Edge edge[N*20];
void del(int x){
dp[++dc]=x;
}
int newnode(){
return dc?dp[dc--]:++cnt;
}
void add(int x,int y,int z=0){
int t=newnode();
edge[t].to=y;
edge[t].nxt=head[x];
edge[t].sze=z;
head[x]=t;
}
}A,B;
int getint(){
int X=0,w=0;char ch=getchar();
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
}
void dfs(int now){
for(int i=A.head[now];i;i=A.edge[i].nxt){
int to=A.edge[i].to;
if(to==fa[now]) continue;
fa[to]=now;son[now]++;
dfs(to);
}
}
signed main(){
freopen("cactus.in","r",stdin);freopen("cactus.out","w",stdout);
n=getint(),m=getint();
for(int i=1;i<n;i++){
int x=getint(),y=getint();
A.add(x,y),A.add(y,x);
} dfs(1);
fa[1]=n+1;son[n+1]=1;
for(int i=1;i<=n+1;i++)
if(son[i])
B.add(i,0,son[i]);
for(int cas=1;cas<=m;cas++){
int x=getint(),ans=0;
if(x>1){
int y=fa[fa[x]],val=tag[y]+tag2[fa[x]];
for(int las=0,i=B.head[y];i;las=i,i=B.edge[i].nxt){
if(B.edge[i].to==val){
if(B.edge[i].sze>1)
B.edge[i].sze--;
else if(las)
B.edge[las].nxt=B.edge[i].nxt,B.del(i);
else
B.head[y]=B.edge[i].nxt,B.del(i);
break;
}
} ans=val+1;
int flag=0;
for(int i=B.head[y];i;i=B.edge[i].nxt){
if(B.edge[i].to==ans){
B.edge[i].sze++;
flag=1; break;
}
} if(!flag)
B.add(y,ans,1);
} for(int i=B.head[x];i;i=B.edge[i].nxt){
B.edge[i].to++;
if(B.edge[i].sze&1) ans^=B.edge[i].to;
} (tot+=1ll*ans*((1ll*cas*cas%mod+cas)%mod)%mod)%=mod;
tag[x]++;tag2[fa[x]]++;
} printf("%lld\n",tot);
return 0;
}
[JZOJ5984] 仙人掌的更多相关文章
- jzoj5984. 【北大2019冬令营模拟2019.1.1】仙人掌 (分块)
题面 题解 数据结构做傻了.jpg 考虑每一个节点,它的儿子的取值最多只有\(O(\sqrt {m})\)种,那么可以用一个双向链表维护儿子的所有取值以及该取值的个数,那么对儿子节点修改一个值就是\( ...
- bzoj1023: [SHOI2008]cactus仙人掌图
学习了一下圆方树. 圆方树是一种可以处理仙人掌的数据结构,具体见这里:http://immortalco.blog.uoj.ac/blog/1955 简单来讲它是这么做的:用tarjan找环,然后对每 ...
- 【BZOJ 1023】【SHOI 2008】cactus仙人掌图
良心的题解↓ http://z55250825.blog.163.com/blog/static/150230809201412793151890/ tarjan的时候如果是树边则做树形DP(遇到环就 ...
- 【BZOJ-1952】城市规划 [坑题] 仙人掌DP + 最大点权独立集(改)
1952: [Sdoi2010]城市规划 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 73 Solved: 23[Submit][Status][ ...
- 【BZOJ-4316】小C的独立集 仙人掌DP + 最大独立集
4316: 小C的独立集 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 57 Solved: 41[Submit][Status][Discuss] ...
- 仙人掌(cactus)
仙人掌(cactus) Time Limit:1000ms Memory Limit:64MB 题目描述 LYK 在冲刺清华集训(THUSC) !于是它开始研究仙人掌,它想来和你一起分享它最近研究的 ...
- 【bzoj1023】仙人掌图
[bzoj1023]仙人掌图 题意 给一棵仙人掌,求直径. \(n\leq 100000\) 分析 分析1:[Tarjan]+[环处理+单调队列优化线性dp]+[树形dp] 分开两种情况处理: ①环: ...
- hdu3594 强连通(仙人掌图)
题意:给定一张有向图,问是否是仙人掌图.仙人掌图的定义是,首先,这张图是一个强连通分量,其次所有边在且仅在一个环内. 首先,tarjan可以判强连通分量是否只有一个.然后对于所有边是否仅在一个环内,我 ...
- 【BZOJ】【1023】【SHOI2008】cactus仙人掌图
DP+单调队列/仙人掌 题解:http://hzwer.com/4645.html->http://z55250825.blog.163.com/blog/static/150230809201 ...
随机推荐
- AX_Function
formrun.owner().GetItemId() if (fr.name() == formstr(inventTransEditDimensions) || fr.name() == form ...
- instr()函数--支持模糊查询
1)instr()函数的格式 (俗称:字符查找函数) 格式一:instr( string1, string2 ) / instr(源字符串, 目标字符串) 格式二:instr( strin ...
- java动态生成验证码图片
package cn.lijun.checkimg; import java.awt.image.BufferedImage;import java.io.BufferedReader; import ...
- Acegi框架
Acegi(Acegi Security)框架,是一个能为基于Spring的企业应用提供强大而灵活安全访问控制解决方案的框架,Acegi已经成为 Spring官方的一个子项目,所以也称为Spring ...
- python伪装浏览器
def get_content(url): req_header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/53 ...
- REdis AOF文件结构分析
REdis-4.0之前的AOF文件没有文件头,而从REdis-4.0开始AOF文件带有一个文件头,文件头格式和RDB文件头相同. REdis-4.0版本,如果开启aof-use-rdb-preambl ...
- vue在element-ui的对话框的编辑控件回车时让焦点跳到下一控件
网上找的回车录入焦点前往一下控件的方式普遍比较复杂,自己不想用.学习了一个下午后似乎搞定.先帖一段代码,以后有时间解释,也请大家指教.利用下面的代码注册自己的v-enterToNext指令,并在el- ...
- Re:uxul
Re: Unbelieveable eXperience of University Life
- Mac 下 Java 多版本切换
Step 1: 安装 jdk1.7 jdk1.8 路径如下: + /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk + /Library/Java/J ...
- 使用Docker搭建CentOS 7 + Apache 2.4+ PHP7
从Docker Hub上Pull最新的CentOS 7镜像并新建容器 # sudo docker pull centos docker run -p 8082:80 --name centos_c - ...