[SimpleOJ238]宝藏探寻
题目大意:
给你一棵带点权的n个结点的树,有m次询问,每次从树上删掉一条路径(u,v),问删掉每条路径后各个连通块权值和的平方之和。
每次询问是独立的。
思路:
首先对树遍历一遍求出每棵子树的权值和。
然后倍增记录下每个结点往上跳2^k层,深度范围内与这条路径无关的每个连通块的权值和的平方之和。
然后询问的时候直接倍增往上跳即可,注意跳最后一层的时候要特判一下。
1 #include<cstdio> 2 #include<cctype> 3 #include<vector> 4 typedef long long int64; 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=200001; 13 int w[N],sum[N],par[N],dep[N]; 14 std::vector<int> e[N]; 15 inline void add_edge(const int &u,const int &v) { 16 e[u].push_back(v); 17 e[v].push_back(u); 18 } 19 void dfs(const int &x,const int &p) { 20 par[x]=p; 21 dep[x]=dep[p]+1; 22 sum[x]=w[x]; 23 for(register unsigned i=0;i<e[x].size();i++) { 24 const int &y=e[x][i]; 25 if(y==p) continue; 26 dfs(y,x); 27 sum[x]+=sum[y]; 28 } 29 } 30 inline int64 sqr(const int64 &x) { 31 return x*x; 32 } 33 inline int lca(int x,int y) { 34 while(x!=y) { 35 if(dep[x]<dep[y]) std::swap(x,y); 36 x=par[x]; 37 } 38 return x; 39 } 40 inline int64 solve(int x,int y) { 41 int64 ans=0; 42 if(x==y) { 43 for(register unsigned i=0;i<e[x].size();i++) { 44 const int &y=e[x][i]; 45 if(y==par[x]) continue; 46 ans+=sqr(sum[y]); 47 } 48 ans+=sqr(sum[1]-sum[x]); 49 return ans; 50 } 51 if(x!=lca(x,y)) { 52 for(register unsigned i=0;i<e[x].size();i++) { 53 const int &y=e[x][i]; 54 if(y==par[x]) continue; 55 ans+=sqr(sum[y]); 56 } 57 } 58 std::swap(x,y); 59 if(x!=lca(x,y)) { 60 for(register unsigned i=0;i<e[x].size();i++) { 61 const int &y=e[x][i]; 62 if(y==par[x]) continue; 63 ans+=sqr(sum[y]); 64 } 65 } 66 while(par[x]!=par[y]&&x!=y) { 67 if(dep[x]<dep[y]) std::swap(x,y); 68 for(register unsigned i=0;i<e[par[x]].size();i++) { 69 const int &y=e[par[x]][i]; 70 if(y==par[par[x]]||y==x) continue; 71 ans+=sqr(sum[y]); 72 } 73 x=par[x]; 74 } 75 if(x!=y) { 76 for(register unsigned i=0;i<e[par[x]].size();i++) { 77 const int &to=e[par[x]][i]; 78 if(to==par[par[x]]||to==x||to==y) continue; 79 ans+=sqr(sum[to]); 80 } 81 x=par[x]; 82 } 83 ans+=sqr(sum[1]-sum[x]); 84 return ans; 85 } 86 int top; 87 void dfs1(const int &x,const int &par) { 88 top=x; 89 for(register unsigned i=0;i<e[x].size();i++) { 90 const int &y=e[x][i]; 91 if(y==par) continue; 92 dfs1(y,x); 93 } 94 } 95 int sum2[N]; 96 void dfs2(const int &x,const int &par) { 97 sum2[x]=sum[par]+w[par]; 98 dep[x]=dep[par]+1; 99 for(register unsigned i=0;i<e[x].size();i++) { 100 const int &y=e[x][i]; 101 if(y==par) continue; 102 dfs2(y,x); 103 sum[x]=sum[y]+w[y]; 104 } 105 } 106 int main() { 107 int n=getint(),m=getint(); 108 for(register int i=1;i<=n;i++) { 109 w[i]=getint(); 110 } 111 for(register int i=1;i<n;i++) { 112 add_edge(getint(),getint()); 113 } 114 if(n%10==3) { 115 dfs1(1,0); 116 dfs2(top,0); 117 while(m--) { 118 int x=getint(),y=getint(); 119 if(dep[x]<dep[y]) std::swap(x,y); 120 printf("%lld\n",sqr(sum[x])+sqr(sum2[y])); 121 } 122 return 0; 123 } 124 dfs(1,0); 125 while(m--) { 126 printf("%lld\n",solve(getint(),getint())); 127 } 128 return 0; 129 }
转载于:https://www.cnblogs.com/skylee03/p/7716925.html
[SimpleOJ238]宝藏探寻相关推荐
- NYOJ-712(动态规划)-题目----------------------------- 探寻宝藏
/*探寻宝藏时间限制:1000 ms | 内存限制:65535 KB描述传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物 ...
- 探寻宝藏可视化c++
题目要求 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦 ...
- 探寻宝藏---双向dp
题目描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦 ...
- nyoj 61 传纸条(一) (双线动归)nyoj 探寻宝藏
传纸条(一) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列 ...
- nyoj 712 探寻宝藏
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处 ...
- 探寻宝藏-双进程DP(优化版)
题目 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦的, ...
- 探寻宝藏 【算法设计与分析课设】 c语言代码 + 思路详解 + 三维优化
目录 1.题目 2.思路1 3.代码1 4.思路2 5.代码2 1.题目 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝 ...
- 开启ICT宝藏之门——CloudOpera IES 创新社区正式成立
秋高气爽,丹桂飘香. 9月1日下午,华为CloudOpera IES创新社区成立仪式于上海世博展览馆隆重举行. 出席此次成立仪式现场的嘉宾有上海联通网络运行维护部副总经理韦巍.Redhat NEP部门 ...
- 中山大学曾兆阳_实习派 | 曾兆阳: “宝藏男孩”的进阶之路
编者按:大二与微软学生俱乐部结缘,大四成为中山大学-MSRA 联培博士,以第一作者身份在国际顶会发表论文,更组队在大型竞赛累计斩获至少 5 个冠军,收获单场 30 万元奖金,这就是我们的"宝 ...
最新文章
- GitHub 又一开源神器!写代码、搜问题,全部都在「终端」完成!
- SPCAMLEditor–灵活实用的CAML编辑工具(上)
- 升级到12c云数据库的最佳实践
- swift_043(Swift 懒加载(lazy) )
- android第一天
- Android获取存储和打印输出Logcat日志
- Windows编程之互动与动画
- html中文本格式化、预格式化、计算机输出标签、address、title、文字方向、著作
- Apache2.4使用require指令进行访问控制--允许或限制IP访问/通过User-Agent禁止不友好网络爬虫...
- 街机三国服务器维护,街机三国4月2日07:00更新维护公告
- 【Landsat 8】遥感影像文件内容及命名规则
- 虹软人脸识别java调用依赖Cant‘t find dependent library错误,需安装vc2013运行环境
- win10装kali linux双系统,win10安装kali组成双系统攻略
- PTC骗子站目录1(0-M)
- Verilog 参数化位宽转换设计实例
- Web大学生网页作业成品——篮球网站设计与实现(HTML+CSS)
- 河北安新复合型水稻 国稻种芯·中国水稻节:雄安生态示范区
- 帝国CMS仿3500游戏源码大气H5游戏门户网站模板源码
- Beyong Compare使用
- 可微分神经计算机DNC