[HDU5799]This world need more Zhu
题面戳我
题意:
给定一棵树,m次操作,每次询问某一棵子树中,或者是某一条路径上,出现次数为a的所有数字之和与出现次数为b的所有数字之和的gcd
原题表述:the \(\gcd\) of the sum of numbers that appears \(a\) times and the sum of numbers that appears \(b\) times in subtree \(u\) or on the path from \(u\) to \(v\) .
sol
你把题目看懂了就会发现这是一道莫队傻逼题
首先输入的数据需要离散化
把子树的询问和路径的询问分开处理,然后子树询问可以直接转化为序列莫队。
路径询问就树上莫队即可。
code
记得多组数据初始化
树链剖分中只有son数组要初始化
莫队需要用到的所有数组都要初始化
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
const int N = 100005;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
struct edge{int to,next;}a[N<<1];
int T,n,len,block,BL,m,col[N],o[N],head[N],cnt;
int fa[N],dep[N],sz[N],son[N],top[N],dfn[N],low[N],ref[N];
int ccnt,bl[N],s[N],tp;
int cnt1,cnt2,vis[N],tot[N];ll sum[N],ans[N];
struct query1{
int l,r,a,b,id;
bool operator < (const query1 &b) const
{
if (l/BL==b.l/BL) return r<b.r;
return l/BL<b.l/BL;
}
}q1[N];
struct query2{
int u,v,a,b,id;
bool operator < (const query2 &b) const
{
if (bl[u]==bl[b.u]) return bl[v]<bl[b.v];
return bl[u]<bl[b.u];
}
}q2[N];
void dfs1(int u,int f)
{
fa[u]=f;dep[u]=dep[f]+1;sz[u]=1;
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (v==f) continue;
dfs1(v,u);
sz[u]+=sz[v];if (sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int up)
{
top[u]=up;dfn[u]=++cnt;ref[cnt]=u;int ttp=tp;
if (son[u]) dfs2(son[u],up);
if (tp-ttp>=block) {++ccnt;while (tp>ttp) bl[s[tp--]]=ccnt;}
for (int e=head[u];e;e=a[e].next)
{
int v=a[e].to;if (v==fa[u]||v==son[u]) continue;
dfs2(v,v);
if (tp-ttp>=block) {++ccnt;while (tp>ttp) bl[s[tp--]]=ccnt;}
}
low[u]=cnt;s[++tp]=u;
}
int lca(int u,int v)
{
while (top[u]^top[v])
{
if (dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
void update(int x)
{
if (!vis[x])
{
vis[x]=1;
sum[tot[col[x]]]-=o[col[x]];
tot[col[x]]++;
sum[tot[col[x]]]+=o[col[x]];
}
else
{
vis[x]=0;
sum[tot[col[x]]]-=o[col[x]];
tot[col[x]]--;
sum[tot[col[x]]]+=o[col[x]];
}
}
void change(int u,int v)
{
while (u^v)
if (dep[u]>dep[v]) update(u),u=fa[u];
else update(v),v=fa[v];
}
ll Gcd(ll A,ll B){return B?Gcd(B,A%B):A;}
int main()
{
T=gi();
for (int zsy=1;zsy<=T;zsy++)
{
printf("Case #%d:\n",zsy);
n=gi();m=gi();block=pow(n,0.6);BL=pow(n,0.5);
for (int i=1;i<=n;i++) col[i]=o[i]=gi();
sort(o+1,o+n+1);len=unique(o+1,o+n+1)-o-1;
for (int i=1;i<=n;i++) col[i]=lower_bound(o+1,o+len+1,col[i])-o;
memset(head,0,sizeof(head));cnt=ccnt=0;
memset(son,0,sizeof(son));
for (int i=1,u,v;i<n;i++)
{
u=gi();v=gi();
a[++cnt]=(edge){v,head[u]};head[u]=cnt;
a[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
dfs1(1,0);cnt=0;dfs2(1,1);
while (tp) bl[s[tp--]]=ccnt;
cnt1=cnt2=0;
for (int i=1,opt,u,v,A,B;i<=m;i++)
{
opt=gi();u=gi();v=gi();A=gi();B=gi();
if (dfn[u]>dfn[v]) swap(u,v);
if (opt==1) q1[++cnt1]=(query1){dfn[u],low[u],A,B,i};
else q2[++cnt2]=(query2){u,v,A,B,i};
}
sort(q1+1,q1+cnt1+1);sort(q2+1,q2+cnt2+1);
int L=1,R=0;
memset(tot,0,sizeof(tot));
memset(sum,0,sizeof(sum));
memset(vis,0,sizeof(vis));
for (int i=1;i<=cnt1;i++)
{
while (L>q1[i].l) L--,update(ref[L]);
while (R<q1[i].r) R++,update(ref[R]);
while (L<q1[i].l) update(ref[L]),L++;
while (R>q1[i].r) update(ref[R]),R--;
ans[q1[i].id]=Gcd(sum[q1[i].a],sum[q1[i].b]);
}
memset(tot,0,sizeof(tot));
memset(sum,0,sizeof(sum));
memset(vis,0,sizeof(vis));
change(q2[1].u,q2[1].v);
int gg=lca(q2[1].u,q2[1].v);
update(gg);ans[q2[1].id]=Gcd(sum[q2[1].a],sum[q2[1].b]);update(gg);
for (int i=2;i<=cnt2;i++)
{
change(q2[i].u,q2[i-1].u);change(q2[i].v,q2[i-1].v);
gg=lca(q2[i].u,q2[i].v);
update(gg);ans[q2[i].id]=Gcd(sum[q2[i].a],sum[q2[i].b]);update(gg);
}
for (int i=1;i<=m;i++) printf("%lld\n",ans[i]);
}
return 0;
}
[HDU5799]This world need more Zhu的更多相关文章
- 2016中国大学生程序设计竞赛 网络选拔赛 I This world need more Zhu
This world need more Zhu Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- hdu 5833 Zhu and 772002 高斯消元
Zhu and 772002 Problem Description Zhu and 772002 are both good at math. One day, Zhu wants to test ...
- hdu 5833 Zhu and 772002 ccpc网络赛 高斯消元法
传送门:hdu 5833 Zhu and 772002 题意:给n个数,每个数的素数因子不大于2000,让你从其中选则大于等于1个数相乘之后的结果为完全平方数 思路: 小于等于2000的素数一共也只有 ...
- HDU 5833 Zhu and 772002
HDU 5833 Zhu and 772002 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- CWNP宣布中国首位CWNE获得者——朱志立(Kevin Zhu)
CWNP宣布中国首位CWNE获得者——朱志立(Kevin Zhu) Kevin Zhu获得了全球CWNE认证无线网络专家的第134号,CWNE被公认为IT行业最难获取的10大认证之一. [ ...
- HDU 5833 Zhu and 772002 (高斯消元)
Zhu and 772002 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5833 Description Zhu and 772002 are b ...
- HDU 5840 This world need more Zhu 树链剖分+暴力
This world need more Zhu 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5840 Description As we all ...
- 魏汝盼医学博士 - Judy Zhu Wei, M.D., F.A.C.O.G.
魏汝盼医学博士 - Judy Zhu Wei, M.D., F.A.C.O.G. 医院(诊所)名称:CAPRI妇产科诊所 妇产科,华人医生,微创妇科手术专科医生,女医生,fountai ...
- HDU 5833 Zhu and 772002(高斯消元)
题意:给n个数,从n个数中抽取x(x>=1)个数,这x个数相乘为完全平方数,求一共有多少种取法,结果模1000000007. 思路:每个数可以拆成素数相乘的形式,例如: x1 2=2^1 * 3 ...
随机推荐
- TensorFlow实战之实现自编码器过程
关于本文说明,已同步本人另外一个博客地址位于http://blog.csdn.net/qq_37608890,详见http://blog.csdn.net/qq_37608890/article/de ...
- [求助][SPOJ MARIOGAM]-高斯消元(内含标程,数据等)
小蒟蒻开始做概率的题之后,遇到了这道题,然而,他发现自己的程序调试了无数次也无法通过,系统总是返回令人伤心的WA, 于是,他决定把这一天半的时间收集到的资料放在网上, 寻求大家的帮助, 也可以节省后来 ...
- Java经典编程题50道之四十四
求0~7所能组成的奇数个数.分析:组成1位数是4个,组成2位数是7*4个,组成3位数是7*8*4个,组成4位数是7*8*8*4个…… public class Example44 { publi ...
- [工具]Microsoft To-Do,简约还是简陋?
1. 简介 微软收购奇妙清单后,由奇妙清单的原班人马打造了一个全新的待办事项应用,就叫"To-Do"(简单粗暴,好像新浪微博直接就叫"微博"的感觉).这个应该刚 ...
- 关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思
关于在windows10中的vmware9.0里面安装的ubuntukylin15.04和windows共享目录的一些反思 一.遇到的问题 如题目所说,在windows的虚拟机中和windo ...
- Ajax检测用户名是否已经注册
程序功能 当用户名输入完成(即用户名输入框失去焦点),利用Ajax检测用户名是否已经注册! 实现过程 利用Ajax向CheckUserServlet发送请求,判断该用户名是否可用.这里只是为了演示Aj ...
- Java文件及文件夹的创建与删除
功能 这个实例实现了在D盘创建一个文件和文件夹,并删除它们. 函数介绍 createNewFile():当文件不存在时,根据绝对路径创建该文件. delete():删除文件或者文件夹. ...
- hdu1496 打表
通常可以想到直接四个for枚举,但是会超时.就算只用三个for也很危险.可以用打表的方法将时间复杂度降到O(n^2),注意到x1,x2,x3,x4的取值区间是关于零对称的,因此可以只考虑正整数部分,洗 ...
- React——diff算法
react的diff算法基于两个假设: 1.不同类型的元素会产生不同的树 2.通过设置key,开发者能够提示那些子组件是稳定的 diff算法 当比较两个树时,react首先会比较两个根节点,接下来具体 ...
- Java中子类能继承父类的私有属性吗?
前段时间去听老师讲课的时候,老师告诉我子类是可以继承父类所有的属性和方法的.当时我是极其疑惑的,因为之前学校考试时这个考点我记得很清楚:子类只能继承父类的非私有属性和方法.老师给我的解释是这样的--先 ...