[JZOJ3397]雨天的尾巴
来源:互联网 发布:nginx 1.8 域名配置 编辑:程序博客网 时间:2024/04/25 17:22
题目大意
一棵
询问所有操作完成之后,所有点个数最多的分别是哪一个种类的信息。
题目分析
将种类离散化,然后直接建权值线段树,在树上线段树合并即可。
每一个修改可以拆成对四个点的单点修改。
时间复杂度
代码实现
#include <algorithm>#include <iostream>#include <cstdio>#include <cctype>#include <cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f;}const int N=100500;const int M=100500;const int Q=M*4;const int E=N-1<<1;const int LGN=18;const int S=N*LGN;const int EL=N<<1;const int LGEL=19;int root[N];struct segment_tree{ int son[S][2],mx[S][2]; int tot; int newnode() { return ++tot,son[tot][0]=son[tot][1]=mx[tot][0]=mx[tot][1]=0,tot; } void update(int rt,int l,int r) { if (mx[l=son[rt][0]][1]>mx[r=son[rt][1]][1]||mx[l][1]==mx[r][1]&&mx[l][0]<mx[r][0]) mx[rt][0]=mx[l][0],mx[rt][1]=mx[l][1]; else mx[rt][0]=mx[r][0],mx[rt][1]=mx[r][1]; } void modify(int &rt,int y,int l,int r,int delta) { if (!rt) rt=newnode(); if (l==r) { mx[rt][0]=y,mx[rt][1]+=delta; return; } int mid=l+r>>1; if (y<=mid) modify(son[rt][0],y,l,mid,delta); else modify(son[rt][1],y,mid+1,r,delta); update(rt,l,r); } void merge(int &rt1,int rt2,int l,int r) { if (!(rt1&&rt2)) { rt1+=rt2; return; } if (l==r) { mx[rt1][1]+=mx[rt2][1]; return; } int mid=l+r>>1; merge(son[rt1][0],son[rt2][0],l,mid),merge(son[rt1][1],son[rt2][1],mid+1,r); update(rt1,l,r); }}t;struct data{ int id,key; data (int id0=0,int key0=0){id=id0,key=key0;}}srt[M];bool operator<(data a,data b){return a.key<b.key;}int last[N],h[N],pos[N],top[N],fa[N],ans[N],typ[N];int change[Q][2]/*tp delta*/,nxt[Q];int n,m,tot,cnt,el,lgel,idx;int next[E],tov[E];int rmq[EL][LGEL];int euler[EL];int C[M][3];void insert(int x,int y){ tov[++tot]=y,next[tot]=last[x],last[x]=tot;}void require(int x,int tp,int delta){ change[++cnt][0]=tp,change[cnt][1]=delta; nxt[cnt]=top[x],top[x]=cnt;}void dfs(int x){ h[x]=h[fa[x]]+1,euler[++el]=x,rmq[el][0]=x,pos[x]=el; for (int i=last[x],y;i;i=next[i]) if (fa[x]!=(y=tov[i])) fa[y]=x,dfs(y),euler[++el]=x,rmq[el][0]=x;}void pre(){ lgel=trunc(log(el)/log(2)); for (int j=1;j<=lgel;j++) for (int i=1;i+(1<<j)-1<=el;i++) rmq[i][j]=h[rmq[i][j-1]]<h[rmq[i+(1<<j-1)][j-1]]?rmq[i][j-1]:rmq[i+(1<<j-1)][j-1];}int getrmq(int l,int r){ int lgr=trunc(log(r-l+1)/log(2)); return h[rmq[l][lgr]]<h[rmq[r-(1<<lgr)+1][lgr]]?rmq[l][lgr]:rmq[r-(1<<lgr)+1][lgr];}int lca(int x,int y){ if ((x=pos[x])>(y=pos[y])) x^=y^=x^=y; return getrmq(x,y);}void calc(int x){ int rt=0; for (int i=last[x],y;i;i=next[i]) if (fa[x]!=(y=tov[i])) calc(y),t.merge(rt,root[y],1,n); for (int i=top[x];i;i=nxt[i]) t.modify(rt,change[i][0],1,n,change[i][1]); ans[x]=t.mx[root[x]=rt][0];}int main(){ freopen("rain.in","r",stdin); freopen("rain.out","w",stdout); n=read(),m=read(); for (int i=1,u,v;i<n;i++) { u=read(),v=read(); insert(u,v),insert(v,u); } dfs(1),pre(); for (int i=1;i<=m;i++) C[i][1]=read(),C[i][2]=read(),srt[i].key=C[i][0]=read(),srt[i].id=i; sort(srt+1,srt+1+m); for (int i=1;i<=m;i++) C[srt[i].id][0]=idx+=(srt[i].key!=srt[i-1].key),typ[idx]=srt[i].key; for (int i=1,u,v,w;i<=m;i++) { u=C[i][1],v=C[i][2],w=C[i][0]; int x=lca(u,v); require(u,w,1),require(v,w,1),require(x,w,-1); if (fa[x]) require(fa[x],w,-1); } calc(1); for (int i=1;i<=n;i++) printf("%d\n",typ[ans[i]]); fclose(stdin); fclose(stdout); return 0;}
0 0
- [JZOJ3397]雨天的尾巴
- 【JZOJ3397】雨天的尾巴
- [JZOJ3397]【GDOI2014模拟】雨天的尾巴
- bzoj3307 雨天的尾巴
- 雨天的尾巴
- [bzoj3307]雨天的尾巴
- 雨天的尾巴
- BZOJ3307: 雨天的尾巴
- bzoj-3307 雨天的尾巴
- bzoj 3307: 雨天的尾巴
- 【JZOJ 3397】 雨天的尾巴
- 【JZOJ 3397】雨天的尾巴
- 【GDOI2014模拟】雨天的尾巴
- 【GDOI2014模拟】雨天的尾巴
- BZOJ 3307: 雨天的尾巴
- BZOJ 3307 雨天的尾巴 线段树
- 【bzoj3307】雨天的尾巴 线段树+树链剖分
- 【GDOI2014模拟】雨天的尾巴 题解+代码
- Leetcode 83. Remove Duplicates from Sorted List
- python中内置函数locals()和gloabls()解析
- Astar Round2A
- Genymotion如何启动网络连接
- web测试方法总结
- [JZOJ3397]雨天的尾巴
- SQL Server 2008 R2安装与使用
- xutils上传json字符串
- Ruby on Rails 使用 Ajax
- LK源码解析 3 thread.c
- hacker常用的运行小助手
- 数据库事务
- Android开发--权限清单
- python的类