Test 6.29 T4 简单数据结构练习
问题描述
费了一番功夫,神犇 CJK 终于完成了前三道题目。“不错,不愧是新一代神犇啊!” JesseLiu 满意地说道,“不过,你在算法方面的功底固然不错。对于数据结构的运用,你又掌握地如何呢?”
听到“数据结构”这四个字,就连身为神犇的 CJK 也不禁吓出一身冷汗。“年轻人,现在,对于我给定一棵树,你需要完成以下操作:
1.修改某个点的权值;
2.查询某两点间路径上所有点的权值和;
3.查询某点子树的权值和。”
CJK 脸上闪过一丝不屑:不就是道链剖裸题吗?
“这只是第一问。”JesseLiu 似乎也觉得这道题太水了,于是补充道:“完成以上所有操作后,我还会有以下几种询问:
- 询问某个点子树上有多少个点的权值小于等于 k;
- 询问某两点之间的路径上有多少点的权值小于等于 k;”
尽管 CJK 是神犇,但遇到这种题,也不禁感到一丝恐惧。还好,通过自己的玄学力量,他联系到了他的同学——你。现在,就请你 A 掉这最后一道水题。
输入格式
第一行一个数 n,表示点的总数。接下来 n-1 行,一行两个整数 x 和 y,表示x 和 y 之间有边相连。接下来一个整数 m1,表示第一问中操作的数量。接下来m1 行表示操作,格式如下:
“1 x y”将点 x 的权值修改为 y;
“2 x y”询问 x 到 y 路径上的点权之和(包括 x 和 y);
“3 x”询问 x 的子树上的点权和(包括 x);
接下来一行 m2,表示第二问中操作的数量。接下来 m2 行描述操作,格式如下:
“1 x y z”询问 x 到 y 的路径上有多少个点的权值小于等于 z;
“2 x y”询问 x 的子树上有多少个点的权值小于等于 y;
每个点的初始权值为 0。
输出格式
对于每一次询问,输出一个整数表示询问的答案。
样例输入输出
样例输入1
3
1 2
1 3
3
1 1 3
1 3 1
3 1
2
2 1 2
1 1 3 1
样例输出1
4
2
1
样例输入2
5
1 2
1 3
3 4
3 5
5
3 1
1 3 1
2 4 5
1 4 -1
3 3
2
1 1 5 0
2 3 -1
解析
对于第一问,显然是一道树链剖分单点修改加区间查询和的裸题,直接做即可。
对于第二问,一个点要产生贡献,当且仅当这个点在查询的范围内(子树or路径),产生的贡献为1。为了满足限制,我们需要保证在询问时,除了小于等于询问值的节点的值为1以外其余节点都为0。我们可以想到,将询问与节点一起记在一个操作数组中,按照第一问的权值或者询问的值从小到大排序。每一个节点视为一个将节点对应的值变为1的操作,询问同第一问。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 500002
using namespace std;
struct opt{
int op,id,x,y,val;
}a[N];
int head[N],ver[N*2],nxt[N*2],l;
int n,m1,m2,i,dfn[N],end[N],tim,ans[N];
int fa[N],size[N],top[N],son[N],dep[N],pos[N],tree[N],cnt;
void insert(int x,int y)
{
l++;
ver[l]=y;
nxt[l]=head[x];
head[x]=l;
}
void dfs1(int x)
{
size[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(y!=fa[x]){
fa[y]=x;
dep[y]=dep[x]+1;
dfs1(y);
if(size[son[x]]<size[y]) son[x]=y;
size[x]+=size[y];
}
}
}
void dfs2(int x,int tp)
{
dfn[x]=++tim;
pos[x]=++cnt;top[x]=tp;
if(son[x]) dfs2(son[x],top[x]);
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(y!=son[x]&&y!=fa[x]) dfs2(y,y);
}
end[x]=tim;
}
void update(int p,int l,int r,int x,int val)
{
if(x<l||r<x) return;
if(l==r){
tree[p]=val;
return;
}
int mid=(l+r)/2;
update(p*2,l,mid,x,val);
update(p*2+1,mid+1,r,x,val);
tree[p]=tree[p*2]+tree[p*2+1];
}
int ask(int p,int l,int r,int ql,int qr)
{
if(r<ql||l>qr) return 0;
if(l>=ql&&r<=qr) return tree[p];
int mid=(l+r)/2;
return ask(p*2,l,mid,ql,qr)+ask(p*2+1,mid+1,r,ql,qr);
}
int find(int u,int v)
{
int f1=top[u],f2=top[v],ans=0;
while(f1!=f2){
if(dep[f1]<dep[f2]) swap(f1,f2),swap(u,v);
ans+=ask(1,1,n,pos[f1],pos[u]);
u=fa[f1];f1=top[u];
}
if(dep[u]>dep[v]) swap(u,v);
return ans+ask(1,1,n,pos[u],pos[v]);
}
int my_comp(const opt &a,const opt &b)
{
if(a.val==b.val) return a.op<b.op;
return a.val<b.val;
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>n;
for(i=1;i<n;i++){
int u,v;
cin>>u>>v;
insert(u,v);
insert(v,u);
}
dfs1(1);
dfs2(1,1);
cin>>m1;
for(i=1;i<=m1;i++){
int op,x,y;
cin>>op;
if(op==1){
cin>>x>>y;
update(1,1,n,pos[x],y);
}
else if(op==2){
cin>>x>>y;
cout<<find(x,y)<<endl;
}
else{
cin>>x;
cout<<ask(1,1,n,dfn[x],end[x])<<endl;
}
}
cin>>m2;
int tmp=m2;
for(i=1;i<=m2;i++){
int op,x,y,z;
cin>>op;
if(op==1){
cin>>x>>y>>z;
a[i]=(opt){op,i,x,y,z};
}
else{
cin>>x>>y;
a[i]=(opt){op,i,x,0,y};
}
}
for(i=1;i<=n;i++) a[++m2]=(opt){0,m2,i,0,ask(1,1,n,pos[i],pos[i])};
memset(tree,0,sizeof(tree));
sort(a+1,a+m2+1,my_comp);
for(i=1;i<=m2;i++){
if(a[i].op==0) update(1,1,n,pos[a[i].x],1);
else if(a[i].op==1) ans[a[i].id]=find(a[i].x,a[i].y);
else ans[a[i].id]=ask(1,1,n,dfn[a[i].x],end[a[i].x]);
}
for(i=1;i<=tmp;i++) cout<<ans[i]<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
总结
一个思路:为了消去影响,可以使一个影响产生在询问以后,通过排序以及适当的转化实现。
Test 6.29 T4 简单数据结构练习的更多相关文章
- python学习总结----简单数据结构
mini-web服务器 - 能够完成简单的请求处理 - 使用http协议 - 目的:加深对网络编程的认识.为后面阶段学习web做铺垫 简单数据结构 - 排列组合 import itertools # ...
- 牛客练习赛22-E.简单数据结构1(扩展欧拉定理降幂 +树状数组)
链接:E.简单数据结构1 题意: 给一个长为n的序列,m次操作,每次操作: 1.区间加 2.对于区间,查询 ,一直到- 请注意每次的模数不同. 题解:扩展欧拉定理降幂 对一个数p取log(p)次的 ...
- [LOJ#2326]「清华集训 2017」简单数据结构
[LOJ#2326]「清华集训 2017」简单数据结构 试题描述 参加完IOI2018之后就是姚班面试.而你,由于讨厌物理.并且想成为乔布斯一样的创业家,被成功踢回贵系. 转眼,时间的指针被指向201 ...
- 简单数据结构题(from 钟子谦——IOI2018集训队自选题)
简单数据结构题(from 钟子谦--IOI2018集训队自选题) 试题描述 给一棵 \(n\) 个点的树,点权开始为 \(0\) ,有 \(q\) 次操作,每次操作是选择一个点,把周围一圈点点权 \( ...
- 简单数据结构———AVL树
C - 万恶的二叉树 Crawling in process... Crawling failed Time Limit:1000MS Memory Limit:32768KB 64b ...
- NYOJ 简单数据结构
NYOJ 2 括号配对问题 栈的简单应用.可使用STL. #include <iostream> #include <cstdio> #include <cstring& ...
- 冬训day3 简单数据结构
A - 简单计算器 模拟加栈..写一写就好,从头到尾扫一遍,分两个栈存,一个存运算符,一个存中间结果,遇到乘除就先处理了,每次遇到加减就处理上一个加减的两个数,结果压进去...同时把这个运算符存进去. ...
- 【正睿多校联盟Day4 T4 简单的数论题】
题目名有毒 由于并没有系统地开始学习数论,所以数论题基本靠暴力. 然鹅本题的题解相当简单: emmm....我当你没说 一个简单易懂的方法是这样的: 1. 欧拉定理的推论 若正整数a,n互质,则对于任 ...
- 【简单数据结构】并查集--洛谷 P1111
题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...
随机推荐
- Linux双网卡绑定和解除
转载双网卡绑定和解除 一定要在服务管理中关闭NetworkManager服务并禁用自动启动,因为NetworkManager服务是实时生效的,一旦设置错,管理员就得回到机房接显示器配置网络连接. 以 ...
- JS-Proxy
Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等). 参考:Proxy - JavaScript | MDN 语法: let p = new Proxy(target, ...
- 阶段1 语言基础+高级_1-3-Java语言高级_07-网络编程_第2节 TCP协议_4_TCP通信的服务器端代码实现
表示服务器的类是ServerSocket 启动服务器端 再启动客户端 客户端代码修改获取服务端会写的数据 先启动服务器端,再启动客户端 客户端打印: 服务器端读取:
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_2_字符输入流读取字符数据
读取的文件有中文也有英文 强转为char类型 缓冲读取多个字符 使用string的构造方法转换为字符输出
- Lucene的步骤
// 1. 采集数据 BookDao bookDao = new BookDaoImpl(); List<Book> bookList = bookDao.queryBookList(); ...
- Spring004--Spring AOP(mooc)
一.Spring AOP概览 1.1.AOP(面向切面编程)是什么 1. AOP是一种编程范式,而不是编程语言. 2.解决特写问题,不能解决所有问题 3.是OOP的补充,不是替代 除了面向切面编程,还 ...
- 整理那些用于基本生存的shell命令
变量定义相关的 export export可以将临时定义的变量定义成环境变量 比如在一个shell中临时定义的一个变量就没法在新打开的那个shell中继续再使用 使用export之后 这个变量就变成了 ...
- Prometheus + AlertManager 邮件报警
安装 wget https://github.com/prometheus/alertmanager/releases/download/v0.13.0/alertmanager-0.13.0.lin ...
- HTTP response status
The status code is a 3-digit number: 1xx (Informational): Request received, server is continuing the ...
- jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线)
jfinal+H5的websocket 实现同一账户在不同地点不同电脑只能登陆一个(互相踢下线):https://blog.csdn.net/liuyifeng1920/article/details ...