BZOJ3307——雨天的尾巴
来源:互联网 发布:mac 打字声音 编辑:程序博客网 时间:2024/04/30 10:48
1、题意:给一棵树,
2、分析:如果我们暴力上链剖的话,时间和空间都会boom!
那么我们考虑树上差分!那么就变成了把从根到某个点添加或删除一种物品。在树上打标记,我们dfs的时候顺便用线段树合并当前这个点的物品。
#include<map>#include<set>#include<cmath>#include<queue>#include<stack>#include<vector>#include<bitset>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define M 100010#define pb push_back#define LL long long#define MOD 1000000007#define inf 2147483647#define pii pair<int,int>#define llinf 4000000000000000000ll#define For(i,x,y) for(int i=(x);i<(y);i++)#define rep(i,x,y) for(int i=(x);i<=(y);i++)#define drep(i,x,y) for(int i=(x);i>=(y);i--)inline int read(){ char ch=getchar();int x=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}inline LL llread(){ char ch=getchar();LL x=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}struct Edge{ int v,Next;} G[M*2];int head[M],tot;int ft[M][20],height[M],en;inline void add(int u,int v){ G[++tot]=(Edge){v,head[u]};head[u]=tot; G[++tot]=(Edge){u,head[v]};head[v]=tot;}inline void dfs(int x){ height[x]=height[ft[x][0]]+1; for(int i=head[x];i!=-1;i=G[i].Next)if(G[i].v!=ft[x][0]){ ft[G[i].v][0]=x;dfs(G[i].v); }}inline void init(int n){ For(j,1,20)rep(i,1,n)ft[i][j]=ft[ft[i][j-1]][j-1];}inline int lca(int x,int y){ if(height[x]>height[y])swap(x,y); int t=height[y]-height[x]; For(i,0,20)if((1<<i)&t)y=ft[y][i]; if(x==y)return x; drep(i,19,0)if(ft[x][i]!=ft[y][i])x=ft[x][i],y=ft[y][i]; return ft[x][0];}struct que{ int x,y,z;} a[M];int b[M],wt[M];struct lz{ int x,d;} q[M*40];vector<lz> h[M];int T[M*40],ls[M*40],rs[M*40],total,res[M];inline lz mx(lz x,lz y){return (x.x>y.x||x.x==y.x&&x.d<y.d)?x:y;}inline void insert(int l,int r,int &o,int x,int y){ if(!o)o=++total;if(l==r){q[o].x+=y;q[o].d=x;return;}int mid=(l+r)/2; if(x<=mid)insert(l,mid,ls[o],x,y);else insert(mid+1,r,rs[o],x,y); q[o]=mx(q[ls[o]],q[rs[o]]);}inline int merge(int l,int r,int x,int y){ if(!x||!y)return x+y;if(l==r){ q[x].x+=q[y].x;return x; }int mid=(l+r)/2;ls[x]=merge(l,mid,ls[x],ls[y]); rs[x]=merge(mid+1,r,rs[x],rs[y]);q[x]=mx(q[ls[x]],q[rs[x]]);return x;}inline lz query(int l,int r,int o){return q[o];} inline void solve(int x){ For(i,0,h[x].size())insert(1,en,T[x],h[x][i].x,h[x][i].d); for(int i=head[x];i!=-1;i=G[i].Next)if(G[i].v!=ft[x][0]){ solve(G[i].v);T[x]=merge(1,en,T[x],T[G[i].v]); }res[x]=query(1,en,T[x]).d;}int main(){ //freopen("0input.in","r",stdin);//freopen(".out","w",stdout); int n=read(),m=read();memset(head,-1,sizeof(head)); For(i,1,n)add(read(),read());dfs(1);init(n);rep(i,1,m){ a[i]=(que){read(),read(),read()};wt[i]=b[i]=a[i].z; if(height[a[i].x]<height[a[i].y])swap(a[i].x,a[i].y); }sort(b+1,b+m+1);int tt=unique(b+1,b+m+1)-b-1;int xt;rep(i,1,m){ xt=lower_bound(b+1,b+tt+1,a[i].z)-b,wt[xt]=a[i].z,a[i].z=xt; }en=tt;rep(i,1,m){ que x=a[i];int LCA=lca(x.x,x.y);if(LCA!=x.y){ h[LCA].pb((lz){x.z,-1});h[x.y].pb((lz){x.z,1}); }h[ft[LCA][0]].pb((lz){x.z,-1});h[x.x].pb((lz){x.z,1}); }solve(1);rep(i,1,n)printf("%d\n",wt[res[i]]); return 0;}
1 0
- BZOJ3307——雨天的尾巴
- bzoj3307 雨天的尾巴
- [bzoj3307]雨天的尾巴
- BZOJ3307: 雨天的尾巴
- 【bzoj3307】雨天的尾巴 线段树+树链剖分
- [BZOJ3307][线段树合并]雨天的尾巴
- [BZOJ3307][雨天的尾巴][树链剖分+线段树]
- 【BZOJ3307】雨天的尾巴(权限题)
- bzoj3307雨天的尾巴(线段树合并)
- BZOJ3307 雨天的尾巴 (树链剖分 线段树合并 dfs相关)
- 【BZOJ3307】雨天的尾巴(树链剖分+树上差分+线段树)
- 雨天的尾巴
- [JZOJ3397]雨天的尾巴
- 雨天的尾巴
- 【JZOJ3397】雨天的尾巴
- bzoj-3307 雨天的尾巴
- bzoj 3307: 雨天的尾巴
- 【JZOJ 3397】 雨天的尾巴
- VIM TAB键不是\t字符解决办法
- 怎么把VS 中的报表ReportViewer设置超链接打开新页面
- Python查询四六级成绩
- 简单赋值语句的逆向
- 包建强:为什么我说Android插件化从入门到放弃?
- BZOJ3307——雨天的尾巴
- parasoft Jtest 使用教程:单元测试和用例生成详细解析
- heck the manual that corresponds to your MySQL server version for the right syntax to use near 'OPTI
- ASM 翻译系列第二弹:ASM 12C 版本新特性
- order_by_、group_by_、having的用法区别
- [BZOJ1025][SCOI2009]游戏(置换+背包dp+数学相关)
- LoadRunner 11 安装及破解
- mysql 使用 group by和 order by 时extra 的执行情况
- java regular expression