设为首页 加入收藏

TOP

[BZOJ1146]CTSC2008网络管理|树上带修改K大(一)
2015-11-21 01:03:21 来源: 作者: 【 】 浏览:6
Tags:BZOJ1146 CTSC2008 网络管理 树上 修改

  树上带修改K大,太可怕。。写了树链剖分+线段树套平衡树+二分和dfs序+主席树两种,每种都是写+调试花了将近5个小时!!我实在是太弱了。。

1. 树链剖分+线段树套平衡树+二分

最显然的做法了,没啥好多说的,不过写起来真是麻烦(我太弱),

一不小心就会把线段树和平衡树的节点的域弄混,犯了超级多傻逼错误。。写这题的时候还把自己树链剖分的风格改了一下,以前的实在是太麻烦了。。查询的时候二分答案,统计比当前的k大的数有多少个就行了。。

2. dfs序+主席树

 考虑不带修改,那么可以对每个节点维护一颗权值线段树记录它到root的数,类型区间K大的,每个点的新树可以由父节点更新log n个节点来得到,所以初始化是O(Nlog N),查询只要把这两个点和lca的权值权值线段树拉出来,二分答案像上面一样搞就行。。如果这两个点是x,y,lca是p,Ui表示i节点的权值线段树,答案就是Ux+Uy-2*Up再加上p的权值。。

 再来想带修改,大思路还是要把树转化成线性序列来搞。。那么就想到dfs序,若修改一个节点的权值,只会改变它的子树上的各点的权值线段树,而这些点再dfs序中又对应的是一段区间,那就有办法了。。用树状数组来维护所有的修改,若点i从a被修改为b,L[i]表示i在dfs序中出现的位置,R[i]表示i的子树上的节点在dfs中出现的最后位置,那么先将L[i]-n的a减去1,b加上1,再讲R[i]+1-n的a加上1,b减去1,那么就完成的对子树区间的修改。。具体查询的时候只要把dfs序当做区间k大那样做就行了,记得要加上原来未修改时的权值线段树。。

树剖+线段树套平衡树+二分:

?

#include
  
   
#include
   
     #define N 80005 #define NN 1600020 #define ls c[x][0] #define rs c[x][1] using namespace std; struct edge{ int e,next; }ed[N*2]; int n,Q,s,e,ne=0,i,nd=0,cnt=0,rt,k,x,y,maxq=0,a[N],q[N],q1[N],fa[N],sz[N],top[N],son[N],d[N],xu[N],root[N*4],l[N*4],r[N*4],lc[N*4],rc[N*4],c[NN][2],size[NN],num[NN],same[NN],pre[NN]; void add(int s,int e) { ed[++ne].e=e; ed[ne].next=a[s];a[s]=ne; } //处理size 选出son void dfs1(int x) { int to,ms=0; sz[x]=1;son[x]=0; for (int j=a[x];j;j=ed[j].next) if (ed[j].e!=fa[x]) { to=ed[j].e;d[to]=d[x]+1; fa[to]=x;dfs1(to); sz[x]+=sz[to]; if (ms
    
     1) {same[x]--;size[x]--;return;} if (ls*rs==0) {root[rt]=ls+rs,pre[ls+rs]=0;return;} merge(ls,rs,rt); } //初始化树套树 void build(int &x,int ll,int rr) { x=++cnt;l[x]=ll;r[x]=rr;root[x]=0; ins(root[x],q1[ll],x,0); if (ll==rr) { lc[x]=rc[x]=0; return; } int mid=(ll+rr)>>1; for (int i=ll+1;i<=rr;i++) ins(root[x],q1[i],x,0); build(lc[x],ll,mid);build(rc[x],mid+1,rr); } void init() { fa[1]=0;d[1]=0;size[0]=0; dfs1(1);dfs2(1,1); cnt=0;build(rt,1,n); } //修改&&询问 void change(int x,int ll,int k) { if (!x) return; del(root[x],q1[ll],x);ins(root[x],k,x,0);//print(root[x]);printf("\n");printf("%d %d %d %d**\n",root[x],l[x],r[x],size[0]); if (ll>(l[x]+r[x])/2) change(rc[x],ll,k);else change(lc[x],ll,k); } int lca(int x,int y) { if (d[top[x]]>d[top[y]]) swap(x,y); while (top[x]!=top[y]) { y=fa[top[y]]; if (d[top[x]]>d[top[y]]) swap(x,y); } return d[x]
     
      k) ans+=size[rs]+same[x]; else if (num[x]==k) return ans+size[rs]; x=c[x][num[x]
      
       r[x]||rr
       
        =r[x]) { // print(root[x]);printf("*\n"); return getsz(root[x],k); } return query(lc[x],ll,rr,k)+query(rc[x],ll,rr,k); } int sum(int x,int y,int k) { int ans=0; while (top[x]!=top[y]) { if (d[top[x]]>d[top[y]]) swap(x,y); ans+=query(rt,xu[top[y]],xu[y],k);//printf("$%d %d %d\n",xu[top[y]],xu[y],ans); y=fa[top[y]]; } ans+=query(rt,min(xu[x],xu[y]),max(xu[x],xu[y]),k); return ans; } void solve(int x,int y,int k) { int p=lca(x,y),l=1,r=maxq,mid,t; if (d[x]+d[y]-2*d[p]+1
        
         >1; t=sum(x,y,mid);//printf("re:%d %d\n",mid,t); if (t>=k) l=mid+1;else r=mid; } printf("%d\n",l); } int main() { freopen("1146.in","r",stdin); scanf("%d%d",&n,&Q); for (i=1;i<=n;i++) scanf("%d",&q[i]),a[i]=0,maxq=max(maxq,q[i]); for (i=1;i dfs序+主席树:
         

?

?

#include
          
           
#include
           
             #include
            
              #define N 80010 #define NN 8000010 using namespace std; struct edge{ int e,xu,next; }ed[N*4];//兼并了图的边和询问lca点对 struct node{ int n,yuan; node(){} node(int n,int yuan):n(n),yuan(yuan){} }num[2*N]; int n,Q,i,ne=0,nd=0,tim=0,cnt=0,tot=0,s,e,sum[2],d[N],a[N],L[N],R[N],fa[N],pre[N],size[NN],lc[NN],rc[NN],lca[N],k[N],x[N],y[N],u[N],h[N],q[N],newq[2*N],root[N],c[N],use[N][2]; int lowbit(int x){return x&-x;} int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);} void add(int s,int e) { ed[++ne].e=e;ed[ne].next=a[s];a[s]=ne; } void add2(int s,int e,int xu) { ed[++ne].e=e;ed[ne].xu=xu;ed[ne].next=h[s];h[s]=ne; } bool cmp(node a,node b) {return a.n
             
              >1; size
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 1088滑雪 记忆化搜索 下一篇POJ 2418 Hardwood Species(字典..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: