100019. 【NOI2017模拟6.26】A
来源:互联网 发布:php 开源社区系统 编辑:程序博客网 时间:2024/06/12 00:08
题目
大意
给出一个大小为n的树,求合法路径个数
一个路径被称为合法当且仅当其路径上没有两个数使得其中的一个数为另外一个数的倍数
n的范围为100000
题解
不妨分两种情况对每一个限制(u,v)所能造成的影响进行讨论
设dfn[u]< dfn[v],dfn[a]< dfn[b](我们设一类(a,b)因为收到了这个限制的影响不能成为合法的路径)
case 1:
v在u的子树内,不妨设g为这条路径中最接近u的点,end[v]表示在v及其子树内dfn最大的点
那么就有 dfn[a]< dfn[g] dfn[v]<=dfn[b]<=end[v] 或者
dfn[v]<=dfn[a]<=end[v] en[g]< dfn[b]
case 2:
v不在u的子树内
这种情况就比较显然了
dfn[u]<=dfn[a]<=end[u] dfn[v]<=dfn[b]<=end[v]
那么第一种情况构成了两个矩形,第二种情况构成了一个矩形
那么问题就转化成了一个二位的平面上有许多的矩形,现在要求它们的并
可以用线段树+扫描线
线段树里面可以维护3个东西,分别是:这一段有没有被一个矩形完全覆盖过,这一条线段的长度以及当前被覆盖的长度
可以发现每次在-1的时候被完全覆盖过的次数都大于1,所以每一次进行修改操作的时候我们不需要关心具体的覆盖情况,只需要维护一下根到每一个会被完全覆盖的点的覆盖情况就可以了
贴代码
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#define fo(i,a,b) for(i=a;i<=b;i++)#define fo1(i,b,a) for(i=b;i>=a;i--)#define ll long longusing namespace std;const int maxn=1e5+5;struct P{ int c1,c2,c3,c4;}cc[maxn*70];struct Q{ ll c,l,cl;}tree[maxn*6];int fi[maxn],ne[maxn*2],dui[maxn*2],qc[maxn];int dfn[maxn],size[maxn],go[maxn*2],be[maxn],ed[maxn],en[maxn];bool bz[maxn];int i,j,k,l,n,x,y,z,now,tp,g,nc,mid,u,v,r;ll ans,sc,pc;void add(int x,int y){ if (fi[x]==0) fi[x]=++now; else ne[qc[x]]=++now; qc[x]=now; dui[now]=y;}void dfs(int x){ printf("%d %d\n",x,tp); dfn[x]=++tp; size[x]=1; bz[x]=true; int i=fi[x]; be[x]=nc+1; while (i){ if (bz[dui[i]]==true){ i=ne[i]; continue; } go[++nc]=dui[i]; i=ne[i]; } ed[x]=nc; i=fi[x]; while (i){ if (bz[dui[i]]==true){ i=ne[i]; continue; } dfs(dui[i]); size[x]+=size[dui[i]]; i=ne[i]; } en[x]=tp;}void maketree(int x,int l,int r){ tree[x].l=r-l+1; if (l==r) return; int mid=(l+r)/2; maketree(x*2,l,mid); maketree(x*2+1,mid+1,r);}int ge1(){ int x,y,z; if (tree[1].c) return tree[1].l; else return tree[1].cl;}int cmp(P x,P y){ return x.c1<y.c1;}void change(int v,int l,int r,int x,int y,int cc){ if (l==x && r==y){ tree[v].c=tree[v].c+cc; if (cc==1) tree[v].cl=tree[v].l; else tree[v].cl=tree[v*2].cl+tree[v*2+1].cl; if (tree[v].c) tree[v].cl=tree[v].l; } else{ int mid=(l+r)/2; if (y<=mid) change(v*2,l,mid,x,y,cc); else if (x>mid) change(v*2+1,mid+1,r,x,y,cc); else{ change(v*2,l,mid,x,mid,cc); change(v*2+1,mid+1,r,mid+1,y,cc); } if (l!=r) tree[v].cl=tree[v*2].cl+tree[v*2+1].cl; if (tree[v].c>0) tree[v].cl=tree[v].l; }}int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); scanf("%d",&n); fo(i,1,n-1){ scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(1); tp=0; fo(i,1,n/2){ j=i+i; while (j<=n){ x=i; y=j; if (dfn[x]>dfn[y]){ k=x; x=y; y=k; } u=x; v=y; if (size[x]+dfn[x]-1>=dfn[y]){ l=be[x]; r=ed[x]; while (r>l){ mid=(l+r)/2; if (dfn[go[mid]]<dfn[y]) l=mid+1; else r=mid; } if (dfn[go[l]]>dfn[y]) l--; g=go[l]; tp++; cc[tp].c1=1; cc[tp].c2=dfn[v]; cc[tp].c3=en[v]; cc[tp].c4=1; tp++; cc[tp].c1=dfn[g]; cc[tp].c2=dfn[v]; cc[tp].c3=en[v]; cc[tp].c4=-1; tp++; cc[tp].c1=dfn[v]; cc[tp].c2=en[g]+1; cc[tp].c3=n; cc[tp].c4=1; tp++; cc[tp].c1=en[v]+1; cc[tp].c2=en[g]+1; cc[tp].c3=n; cc[tp].c4=-1; } else{ tp++; cc[tp].c1=dfn[u]; cc[tp].c2=dfn[v]; cc[tp].c3=en[v]; cc[tp].c4=1; tp++; cc[tp].c1=en[u]+1; cc[tp].c2=dfn[v]; cc[tp].c3=en[v]; cc[tp].c4=-1; } j+=i; } } sort(cc+1,cc+tp+1,cmp); maketree(1,1,n); i=1; ans=(n*(n-1))/2; while (i<=tp){ v=cc[i].c1; pc=(cc[i].c1-cc[i-1].c1)*ge1(); ans-=pc; while (cc[i].c1==v){ if (cc[i].c2<=cc[i].c3) change(1,1,n,cc[i].c2,cc[i].c3,cc[i].c4); i++; } } printf("%lld\n",ans); return 0;}
阅读全文
0 0
- 100019. 【NOI2017模拟6.26】A
- 【NOI2017模拟6.26】A
- [JZOJ100019] 【NOI2017模拟6.26】A
- 【JZOJ 100019】【NOI2017模拟6.26】A
- JZOJ 100019【NOI2017模拟6.26】A
- jzoj 5006. 【NOI2017模拟3.8】A 树形dp
- NOI2017模拟3.1 总结
- NOI2017模拟3.8 总结
- 【NOI2017模拟3.30】原谅
- 【NOI2017模拟4.2】查询
- 【NOI2017模拟4.2】押韵
- 【NOI2017模拟6.29】呵呵
- 【NOI2017模拟6.2】字符串
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- [JZOJ100003]【NOI2017模拟.4.1】 Tree
- 【JZOJ5036】【NOI2017模拟3.30】原谅
- 【JZOJ5037】【NOI2017模拟3.30】轮回
- 【JZOJ5040】【NOI2017模拟4.2】押韵
- 线上服务内存OOM问题定位三板斧
- 一只爬虫带你看世界【1】
- 文件的读写代码块(二)
- 习题三3.2
- 10.23刷题记录
- 100019. 【NOI2017模拟6.26】A
- Java反射机制
- 为什么在java中不能创建泛型数组
- html上传文件
- 【安全牛学习笔记】CSRF跨站请求伪造攻击漏洞的原理及解决办法
- LeetCode Add Two Numbers
- UVa 133 The Dole Queue
- ROS小白碰壁记之4 读入地图
- free_low_memory_core_early