bzoj4538 [Hnoi2016]网络
2016-04-20 20:50
369 查看
比较容易想到的做法是树链剖分,每个线段树节点维护一个集合,对于一个修改路径操作,我们可以将线段树上不包含操作路径的节点的区间全部都进行一次修改,这种区间个数是logn级别的,这样询问的复杂度是O(qlogn),修改的复杂度是O(q(logn^3)),居然给卡过了。。。
代码
代码
#include<cstdio> #include<algorithm> #include<vector> #include<set> #define mp make_pair #define pb push_back #define fi first #define sc second #define N 600000 using namespace std; typedef long long ll; int n,m,a,b,i,dp,deep ; int pre ,p ,tt ,f ,size ,go ,gf ,id ,tot; int l ,r ; multiset<int> s ; vector<pair<int,int> >vec; struct Q{ int l,r,w,typ; }q ; void link(int x,int y) { dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; } void dfs1(int x,int fa) { int i=p[x]; size[x]=1; while (i) { if (tt[i]!=fa) { deep[tt[i]]=deep[x]+1; dfs1(tt[i],x); if (size[tt[i]]>size[go[x]]) go[x]=tt[i]; size[x]+=size[tt[i]]; } i=pre[i]; } } void dfs2(int x,int fa,int Fa) { int i=p[x]; tot++;id[x]=tot;gf[x]=Fa;f[x]=fa; if (go[x]) dfs2(go[x],x,Fa); while (i) { if ((tt[i]!=fa)&&(tt[i]!=go[x])) dfs2(tt[i],x,tt[i]); i=pre[i]; } } void build(int x,int a,int b) { l[x]=a;r[x]=b; if (b-a>1) { int m=(a+b)>>1; if (a<m) build(2*x,a,m); if (m<b) build(2*x+1,m,b); } } void change(int x,int a,int b,int c) { if ((a<=l[x])&&(r[x]<=b)) { if (c>0) s[x].insert(c); else s[x].erase(s[x].find(-c)); return; } int m=(l[x]+r[x])>>1; if (a<m) change(2*x,a,b,c); if (m<b) change(2*x+1,a,b,c); } int query(int x,int a,int b) { int ans; if (s[x].empty()) ans=-1;else ans=*(--s[x].end()); if ((a<=l[x])&&(r[x]<=b)) return ans; int m=(l[x]+r[x])>>1; if (a<m)ans=max(ans,query(2*x,a,b)); if (m<b)ans=max(ans,query(2*x+1,a,b)); return ans; } void gao(int a,int b,int c) { vec.clear(); int cnt=0; while (1) { int da=deep[gf[a]],db=deep[gf[b]]; if ((da<db)||(da==db)&&(deep[a]<deep[b])) a^=b^=a^=b; if (gf[a]==gf[b]) { vec.pb(mp(id[b],id[a])); break; } else { vec.pb(mp(id[gf[a]],id[a])); a=f[gf[a]]; } } sort(vec.begin(),vec.end()); int head=0; for (int i=0;i<vec.size();i++) { if (head!=vec[i].fi-1) change(1,head,vec[i].fi-1,c); head=vec[i].sc; } if (head!=n) change(1,head,n,c); } int main() { scanf("%d%d",&n,&m); for (i=1;i<n;i++) { scanf("%d%d",&a,&b); link(a,b);link(b,a); } dfs1(1,0); dfs2(1,0,1); build(1,0,n); for (i=1;i<=m;i++) { scanf("%d%",&q[i].typ); if (q[i].typ==2) { scanf("%d",&q[i].w); int tmp=id[q[i].w]; printf("%d\n",query(1,tmp-1,tmp)); } else if (q[i].typ==0) { scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].w); gao(q[i].l,q[i].r,q[i].w); } else { scanf("%d",&q[i].w); int tmp=q[i].w; gao(q[tmp].l,q[tmp].r,-q[tmp].w); } } }
相关文章推荐
- bzoj 4538: [Hnoi2016]网络 树链剖分
- 判断项目的网络是否可用然后打开设置面板
- 2016西电校赛网络赛 Problem F 方格填数
- 网络:NSURLSession 下载文件
- 2016西电校赛网络赛 Problem E 删除字符
- Android基于http的网络请求async-http框架
- 基于Windows的迭代回声服务器端/客户端(基于TCP的服务器端/客户端)
- 2016西电校赛网络赛 Problem D 抢人头
- 2016西电校赛网络赛 Problem C 寻找万神
- 2016西电校赛网络赛Problem B 猴子吃桃 II
- 2016西电校赛网络赛 Problem A z1+z2
- HTML5第7次课堂笔记(图片验证码的应用,xmlhttprequest对象的使用,跨域)
- 网络:NSURLSession
- HTTP笔记
- bzoj4538: [Hnoi2016]网络
- 解决 nginx https反向代理http协议 302重定向localtion到http问题
- linux 网络编程基础(四)read,write,connect, accept 超时封装
- IP地址、子网掩码、网络号、主机号、网络地址、主机地址
- android开发网络请求
- Android开发请求网络方式