Description

Solution

  • 考虑分治,将每一个询问挂在包括它的最大的区间中。
  • 只考虑中点往右的区间的贡献,那么每一个点对于覆盖它的最早的时间有一个贡献。
  • 我们建一个虚树,并且用并查集路径压缩,即覆盖过的点不再走那么就可以保证时间了。
  • 而覆盖的贡献我们记录在一个以时间为下标的树状数组中,便于之后的查询。
  • 然后再考虑从中点往左边处理覆盖操作,并同时处理左端点在当前位置的询问。
  • 但是我们注意到如果一个点在这里的覆盖中被覆盖到,那么其实右边的覆盖操作是无效的,所以要重新用一个并查集完成这个操作,并且如果当前点对于右边的某个时间有贡献,把它的贡献撤回,直接在当前算。
  • 注意不但点要记录是否被覆盖,边也要记录是否被覆盖。
  • 时间复杂度n log n2
  • 另外还有LCT的简单做法,又短又快,我这个快要调晕了。。。。。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 100005
#define maxp 17
#define ll long long
using namespace std;int n,m,q,i,j,k,x,y,l,r;
int em,e[maxn*2],nx[maxn*2],ls[maxn];
int fa[maxn][maxp],dep[maxn],totd,dfn[maxn];
int u[maxn],v[maxn],lca[maxn],lq[maxn],rq[maxn],fr[maxn];
ll a[maxn],sum[maxn],ans[maxn];int p[maxn];
int cmp(int a,int b){return fr[a]<fr[b]||fr[a]==fr[b]&&lq[a]>lq[b];}int read(){int x=0; char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar());for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x;
}void insert(int x,int y){em++; e[em]=y; nx[em]=ls[x]; ls[x]=em;em++; e[em]=x; nx[em]=ls[y]; ls[y]=em;
}void DFS(int x,int p){fa[x][0]=p,dep[x]=dep[p]+1,sum[x]=sum[p]+a[x],dfn[x]=++totd;for(int i=1;i<maxp;i++) fa[x][i]=fa[fa[x][i-1]][i-1];for(int i=ls[x];i;i=nx[i]) if (e[i]!=p)DFS(e[i],x);
}int getlca(int x,int y){if (dep[x]<dep[y]) swap(x,y);for(int i=maxp-1;i>=0;i--) if (dep[fa[x][i]]>=dep[y])x=fa[x][i];if (x==y) return x;for(int i=maxp-1;i>=0;i--) if (fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];return fa[x][0];
}int Lim;
struct Treearry{ll s[maxn];void add(int x,ll delta){for(;x<=Lim;x+=x&-x) s[x]+=delta;}void clear(){for(int i=1;i<=Lim;i++) s[i]=0;}ll sum(int x,ll S=0){for(;x;x-=x&-x) S+=s[x];return S;}
} T;int que[maxn];
int cmp2(int a,int b){return lq[a]<lq[b];};
int bz[maxn],tot,d[maxn],now,cnt,f[maxn],Fa[maxn],b[maxn];
int mi[maxn],mi0[maxn],mx[maxn],mx0[maxn];
int cmp3(int a,int b){return dfn[a]<dfn[b];};
int father(int x){return (f[x]==x)?x:f[x]=father(f[x]);}
int cmp4(int a,int b){return lq[a]>lq[b];}ll jump(int x,int p,int tim){ll s=0; x=father(x);while (dep[x]>dep[p]){if (mi[x]==0) mi[x]=tim,s+=a[x];mi0[x]=tim,s+=sum[x]-a[x]-max(sum[Fa[x]],sum[p]);f[x]=Fa[x],x=father(Fa[x]);}return s;
}ll jump0(int x,int p){ll s=0; x=father(x);while (dep[x]>dep[p]){if (mi[x]) T.add(mi[x],-a[x]),mi[x]=0;if (mi0[x]) {T.add(mi0[x],-(sum[x]-a[x]-max(sum[Fa[x]],sum[p])));mi0[x]=0;}if (!mx[x]) mx[x]=1,s+=a[x];mx0[x]=1,s+=sum[x]-a[x]-max(sum[Fa[x]],sum[p]);f[x]=Fa[x],x=father(Fa[x]);}return s;
}void Doit(int l,int r,int t){cnt=0;for(;now<=q&&fr[p[now]]==t;now++) que[++cnt]=p[now];if (cnt){int mid=(l+r)/2;l=lq[que[1]],r=rq[que[1]];for(int i=2;i<=cnt;i++) l=min(l,lq[que[i]]),r=max(r,rq[que[i]]);d[tot=1]=1,bz[1]=1;for(int i=l;i<=r;i++) {if (!bz[u[i]]) d[++tot]=u[i],bz[u[i]]=1;if (!bz[v[i]]) d[++tot]=v[i],bz[v[i]]=1;}sort(d+1,d+1+tot,cmp3);int totm=0,w=1; b[w]=d[1];for(int i=2;i<=tot;i++){int x=b[w],y=b[w-1],z=getlca(x,d[i]);if (!bz[z]) d[tot+(++totm)]=z,bz[z]=1;if (z==x) b[++w]=d[i]; else{while (dfn[y]>dfn[z]){Fa[x]=y,w--;x=b[w],y=b[w-1],z=getlca(x,d[i]);if (!bz[z]) d[tot+(++totm)]=z,bz[z]=1;}if (dfn[y]==dfn[z]) Fa[x]=y,w--; elseFa[x]=z,b[w]=z;b[++w]=d[i];}}while (w>1) Fa[b[w]]=b[w-1],w--;tot+=totm;for(int i=1;i<=tot;i++) f[d[i]]=d[i];Lim=r-mid;for(int i=mid+1;i<=r;i++){T.add(i-mid,jump(u[i],lca[i],i-mid)+jump(v[i],lca[i],i-mid)+(mi[lca[i]]==0)*a[lca[i]]);if (mi[lca[i]]==0) mi[lca[i]]=i-mid;}for(int i=1;i<=tot;i++) f[d[i]]=d[i];int now0=1; ll ss=0;for(int i=mid;i>=l&&now0<=cnt;i--){ss+=jump0(u[i],lca[i])+jump0(v[i],lca[i]);if (mi[lca[i]]) T.add(mi[lca[i]],-a[lca[i]]),mi[lca[i]]=0;if (!mx[lca[i]]) ss+=a[lca[i]],mx[lca[i]]=1;for(;now0<=cnt&&lq[que[now0]]==i;now0++) ans[que[now0]]=ss+T.sum(rq[que[now0]]-mid);}T.clear();for(int i=1;i<=tot;i++) bz[d[i]]=0;for(int i=1;i<=tot;i++) mi[d[i]]=mi0[d[i]]=mx[d[i]]=mx0[d[i]]=0;}
}int he,ta,D0[maxn*20][3];void Merge(){he=0,ta=1;D0[1][0]=1,D0[1][1]=m,D0[1][2]=1;while (he<ta){he++;int l=D0[he][0],r=D0[he][1],mid=(l+r)/2,t=D0[he][2];Doit(l,r,t);if (l<r){ta++,D0[ta][0]=l,D0[ta][1]=mid,D0[ta][2]=t*2;ta++,D0[ta][0]=mid+1,D0[ta][1]=r,D0[ta][2]=t*2+1;}}
}int main(){freopen("star.in","r",stdin);freopen("star.out","w",stdout);n=read(),m=read(),q=read();for(i=1;i<=n;i++) a[i]=read();for(i=1;i<n;i++) x=read(),y=read(),insert(x,y);DFS(1,0);for(i=1;i<=m;i++) u[i]=read(),v[i]=read(),lca[i]=getlca(u[i],v[i]);for(i=1;i<=q;i++) {lq[i]=read(),rq[i]=read();int l=1,r=m,t=1;while (l<r){int mid=(l+r)/2;if (rq[i]<=mid) r=mid,t=t*2; else if (lq[i]>mid) l=mid+1,t=t*2+1; else {fr[i]=t;break;}}if (l==r) fr[i]=t;p[i]=i;}sort(p+1,p+1+q,cmp);now=1,Merge();for(i=1;i<=q;i++) printf("%lld\n",ans[i]);
}

JZOJ6362. 【NOIP2019模拟2019.9.18】数星星(star)相关推荐

  1. 6360. 【NOIP2019模拟2019.9.18】最大菱形和(rhombus)

    Description Input Output Sample Input 5 5 2 0 1 5 7 3 -4 2 0 -9 8 3 9 0 7 8 2 -4 5 -7 1 4 5 8 7 0 6 ...

  2. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目 题目大意 有个无限长的数列an{a_n}an​,a1=1a_1=1a1​=1,an=an−1+maxdightk(an−1)a_n=a_{n-1}+maxdight_k(a_{n-1})an​= ...

  3. jzoj6065-[NOI2019模拟2019.3.18]One?One!【FFT】

    正题 题目链接:https://gmoj.net/senior/#main/show/6065 题目大意 oneness(x)oneness(x)oneness(x)表示xxx的约数中全是111的数的 ...

  4. 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]

    题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数xxx和yyy,将其删去,并在原来位置插入x+2yx+2yx+2y. 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...

  5. 【THUWC2019模拟2019.1.18】Counting

    Description 羽月最近发现,她发动能力的过程是这样的: 构建一个 V (V<=100)个点的有向图 G,初始为没有任何边,接下来羽月在脑中构建出一个长度为 E 的边的序列,序列中元素两 ...

  6. jzoj6009. 【THUWC2019模拟2019.1.18】Counting (dp)

    Description 羽月最近发现,她发动能力的过程是这样的: 构建一个 V 个点的有向图 G,初始为没有任何边,接下来羽月在脑中构建出一个长度为 E 的边的序列,序列中元素两两不同,然后羽月将这些 ...

  7. jzoj6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题解 真的都快忘了. 首先,我们考虑排序,求出一个神奇的排列方式,也就是dfn序. 那么答案必定是在dfn序里面一些连续的段连接起来. 然后我们就判断这玩意儿是否满足在a里面出现过. 于是现在分两步走 ...

  8. jzoj6067-[NOI2019模拟2019.3.18]More?More!【dp】

    正题 题目链接:https://gmoj.net/senior/#main/show/6067 题目大意 nnn个点的一张竞赛图,第iii个点向第jjj个点(i<j)(i<j)(i< ...

  9. 6009. 【THUWC2019模拟2019.1.18】Counting

    题意: 羽月最近发现,她发动能力的过程是这样的: 构建一个 VVV 个点的有向图 GGG,初始为没有任何边,接下来羽月在脑中构建出一个长度为 EEE 的边的序列,序列中元素两两不同,然后羽月将这些边依 ...

最新文章

  1. 数据预处理之独热编码(One-Hot Encoding)
  2. [转] python运行时内存分析工具meliae
  3. 查看手机截图的坐标信息
  4. Python深浅拷贝教程-面试必问内容
  5. DevExpress破解和消除弹出框问题
  6. Appium Java
  7. 组合的输出(信息学奥赛一本通-T1317)
  8. JS对象与JSON串互转
  9. 从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。...
  10. Oracle大表清理truncate .. reuse storage
  11. 非标准硬件控制之增加系统API
  12. ISP PIPLINE Denoise 之 space domain denoise 空域降噪
  13. 将已有的文件夹添加到git
  14. 基于微信小程序的体育课评分系统小程序
  15. 学数学建模算法对计算机的好处,数学建模中常见十种算法 (期末论文).doc
  16. 怎么更改锁定计算机背景图片,电脑锁屏背景图片如何更改
  17. xUnit.net入门
  18. css简易手风琴效果
  19. JavaEE 7教程
  20. I2C接口的KSZ9897 Switch

热门文章

  1. 测试人员在软件开发过程中的任务是什么?
  2. web前端期末大作业 html+css+javascript网页设计实例 企业网站制作 (绿色植物网站设计)...
  3. 个人认为安卓开发前景
  4. LNK1104:无法打开文件 “.exe”
  5. k-fold cross validation 相关的帖子、论文 建议收藏哦 ~
  6. Java之数组实现增删改
  7. 【模式匹配】之 —— Sunday算法
  8. linux cadaver 命令,备份Linux系统的数据到坚果云
  9. 使用Python将文件名中的汉字序号改为阿拉伯数字序号
  10. STM32实例-蜂鸣器实验