HPU 1458 (数状数组,利用的很神奇)
来源:互联网 发布:杭州投融界网络靠谱吗 编辑:程序博客网 时间:2024/05/21 06:11
文件统计 [数据结构]
题目描述
“星农”是一个追求效率的公司,公司内的文件管理系统也不例外。现有n个文件夹分别命名为1,2,3…n,它们构成一个文件目录,1作为此文件目录的根目录,其它文件夹均为1号目录的直接子目录或间接子目录。每个目录里初始时没有任何文件。
现在有三种操作:
1.add x y –> 向x号目录里添加y个文件
2.delete x y –> 向x号目录里删除y个文件,如果目录中文件数不足y,则输出”error”,不删除文件并结束本次操作。
3.query x –> 查询从x号文件夹到根目录(1号文件夹),其文件个数之和。
输入
第一行输入一个整数T,表示有T组数据。
T组数据中,第一行输入两个整数n、m,表示有n个目录和m次操作。
接下来n-1行,每行输入两个整数x、y,表示x和y互为父子目录。
然后m行表示m次操作,输入方式见样例及题目描述。
1 ≤ T ≤ 20
1 ≤ n,m,x,y ≤ 23333
输出
对于delete操作,若x号目录文件个数不足y个,则输出”error”(不加双引号);
对于query操作,输出一个整数表示要查询信息。
样例输入
1
5 5
1 2
2 4
2 5
1 3
add 5 2
query 2
delete 3 1
add 1 5
query 5
样例输出
0
error
7
地址:http://acm.hpu.edu.cn/problem.php?id=1458
这道题刚开始我一看就知道是线段树和树状数组能解决的,但是自己一直想不懂怎么用
MY 一直想分层 每次只要算上一层的加上自己这层的,一直超时,看了题解后发现了一个大坑 接下来n-1行,每行输入两个整数x、y,表示x和y互为父子目录。就是标红的这一句,他只说明了是父子关系而并没有说明谁是父谁是子,后来研究了一会发现我的思路也有问题,当分支多时会出bug 如果一个文件夹的父文件夹那一级有多个,就会出错!!!
正确思路 :题解思路!!
先看图
就例如这个 先用dfs跑一边 以那个顺序作为树状数组 dj1(图上为up) 代表进入文件夹的时间 dj2(图上为down)是出文件夹的时间.看添加,例如在二号文件夹添加文件 那么受到影响的就是 2 4 5 6 2 那么如何让后面的不搜影响呢 所以就要在 dj1的位置加上文件数 而在dj2处减去文件数,这样受到影响的就只有他们中间的了,另外开个数组存下每个文件夹里的文件数,方便del
由于改了多次有点乱,先凑活吧
#include<bits/stdc++.h>using namespace std;#define ll long long#define rd(a) scanf("%d",&a)#define rl(a) scanf("%lld",&a)#define inf 0x3f3f3f3fll sum[56667];int dj1[23337];int dj2[23337];ll vis[23337];int o;struct node{ int v,next;} ss[46679];int head[23338];inline void tre_add(int u,int v){ ss[o].next=head[u]; ss[o].v=v; head[u]=o++;}void add(int x,int val,int n){ while(x<=n) { sum[x]+=val; x+=x&-x; }}ll query(int x){ ll ans=0; while(x>0) { ans+=sum[x]; x-=x&-x; } return ans;}int v[23399];int cnt;void dfs(int ii){ dj1[ii]=cnt++; for(int i=head[ii]; ~i; i=ss[i].next) { if(!v[ss[i].v]) { v[ss[i].v]=1; dfs(ss[i].v); } } dj2[ii]=cnt++;}int main(){ //freopen("in.txt", "r", stdin); int t; rd(t); while(t--) { o=0;cnt=1; memset(v,0,sizeof(v)); memset(vis,0,sizeof(vis)); memset(sum,0,sizeof(sum)); memset(head,-1,sizeof(head)); int n,m; rd(n),rd(m); for(int i=1; i<n; i++) { int a,b; rd(a); rd(b); tre_add(a,b); tre_add(b,a); } v[1]=1; dfs(1); for(int i=0; i<m; i++) { char s[30]; int a,b; scanf("%s",s); if(s[0]=='a') { rd(a); rd(b); add(dj1[a],b,2*n); add(dj2[a],-b,2*n); vis[a]+=b; } else if(s[0]=='q') { rd(a); ll k=query(dj1[a]); printf("%lld\n",k); } else { rd(a); rd(b); if(vis[a]<b) { puts("error"); } else { vis[a]-=b; add(dj1[a],-b,2*n); add(dj2[a],b,2*n); } } } } return 0;}
官方题解 :http://acm.hpu.edu.cn/showsource.php?id=74552
加油!!
- HPU 1458 (数状数组,利用的很神奇)
- 【HPU】[1733]神奇的数字9
- 【HPU】神奇的操作 【vector +二分 】
- hpu-1690-CZY的组合数烦恼
- hpu-1690-CZY的组合数烦恼
- 神奇的浮点数
- 神奇的catalan数
- 神奇的Catalan数
- 神奇的魔法数
- 神奇的花朵数
- Universe7的神奇数
- 神奇的数组操作
- 利用数组,实现回文数的判断
- 物理学之神奇的数
- 找出神奇的“水仙花”数
- 神奇的卡特兰数
- 1017 -- 神奇的立方数
- 1191: 神奇的立方数
- ROS安装hector_quadrotor
- java
- 设计模式学习--单例模式
- (连载)一个很长的梦——(二)
- Java基础精选,你答对了几道?
- HPU 1458 (数状数组,利用的很神奇)
- SpringMVC(9):JSP报错:#{...} is not allowed in template text
- java 框架之间的比较
- 解决问题:windows10安装MATLAB闪退或者安装没反应
- Ubuntu Chromium启动不了
- LeetCode 422 Find All Duplicates in an Array
- 238. Product of Array Except Self(第十三周)
- Servlet 生命周期、工作原理
- Ionic3 iOS真机及模拟器运行http请求失败