[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 ...
随机推荐
- 主机性能监控之wmi 获取进程信息
标 题: 主机性能监控之wmi 获取进程信息作 者: itdef链 接: http://www.cnblogs.com/itdef/p/3990499.html 欢迎转帖 请保持文本完整并注明出处 仅 ...
- 使用android访问SQLServer数据库
1.SQL驱动 下载可以支持android的SQL驱动,下载地址http://sourceforge.net/projects/jtds/files/ 注意只能下载1.2.7版本.android不支持 ...
- [uboot] (第三章)uboot流程——uboot-spl代码流程
http://blog.csdn.net/ooonebook/article/details/52957395 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...
- 根据Excel模板存储数据,并下载
@RequestMapping("/exportList") @ResponseBody public Map<String, Object> exportList(H ...
- s6-2 UDP
User Datagram Protocol UDP 是一个无连接的(connectionless)的传输层协议 UDP传输数据段,无须建立连接 UDP 在 RFC 768中描述 很多 ...
- jq的事件对象
- 14.2.4HTML5约束API验证
<body> <form> <!-- required属性在提交表单时不能空着 这个属性适用于<input> <textarea> <sel ...
- uva1673(后缀自动机)
后缀自动机还是只会打板子,已经知道它是个什么东西了,但还是和它的构造联系不起来..先背板子吧. 后缀自动机有一个很好的特性就是可以涵盖所有不重复的子串,我们利用这一点在它上面dp就行了: 代码参考:h ...
- 11.webview、shareSDK
布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:la ...
- Git入门基础详情教程
前言 写了一篇文章<一篇文章了解Github和Git教程>还觉得不错,继续写了<为了Github默默付出,我想了解你>,那么继续写Git 基础知识. Git 官网:https: ...