bzoj4538 [Hnoi2016]网络
比较容易想到的做法是树链剖分,每个线段树节点维护一个集合,对于一个修改路径操作,我们可以将线段树上不包含操作路径的节点的区间全部都进行一次修改,这种区间个数是logn级别的,这样询问的复杂度是O(qlogn),修改的复杂度是O(q(logn^3)),居然给卡过了。。。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 #include<set> 5 #define mp make_pair 6 #define pb push_back 7 #define fi first 8 #define sc second 9 #define N 600000 10 using namespace std; 11 typedef long long ll; 12 int n,m,a,b,i,dp,deep[N]; 13 int pre[N],p[N],tt[N],f[N],size[N],go[N],gf[N],id[N],tot; 14 int l[N],r[N]; 15 multiset<int> s[N]; 16 vector<pair<int,int> >vec; 17 struct Q{ 18 int l,r,w,typ; 19 }q[N]; 20 void link(int x,int y) 21 { 22 dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y; 23 } 24 void dfs1(int x,int fa) 25 { 26 int i=p[x]; 27 size[x]=1; 28 while (i) 29 { 30 if (tt[i]!=fa) 31 { 32 deep[tt[i]]=deep[x]+1; 33 dfs1(tt[i],x); 34 if (size[tt[i]]>size[go[x]]) go[x]=tt[i]; 35 size[x]+=size[tt[i]]; 36 } 37 i=pre[i]; 38 } 39 } 40 void dfs2(int x,int fa,int Fa) 41 { 42 int i=p[x]; 43 tot++;id[x]=tot;gf[x]=Fa;f[x]=fa; 44 if (go[x]) dfs2(go[x],x,Fa); 45 while (i) 46 { 47 if ((tt[i]!=fa)&&(tt[i]!=go[x])) 48 dfs2(tt[i],x,tt[i]); 49 i=pre[i]; 50 } 51 } 52 void build(int x,int a,int b) 53 { 54 l[x]=a;r[x]=b; 55 if (b-a>1) 56 { 57 int m=(a+b)>>1; 58 if (a<m) build(2*x,a,m); 59 if (m<b) build(2*x+1,m,b); 60 } 61 } 62 void change(int x,int a,int b,int c) 63 { 64 if ((a<=l[x])&&(r[x]<=b)) 65 { 66 if (c>0) 67 s[x].insert(c); 68 else 69 s[x].erase(s[x].find(-c)); 70 return; 71 } 72 int m=(l[x]+r[x])>>1; 73 if (a<m) change(2*x,a,b,c); 74 if (m<b) change(2*x+1,a,b,c); 75 } 76 int query(int x,int a,int b) 77 { 78 int ans; 79 if (s[x].empty()) ans=-1;else ans=*(--s[x].end()); 80 if ((a<=l[x])&&(r[x]<=b)) return ans; 81 int m=(l[x]+r[x])>>1; 82 if (a<m)ans=max(ans,query(2*x,a,b)); 83 if (m<b)ans=max(ans,query(2*x+1,a,b)); 84 return ans; 85 } 86 void gao(int a,int b,int c) 87 { 88 vec.clear(); 89 int cnt=0; 90 while (1) 91 { 92 int da=deep[gf[a]],db=deep[gf[b]]; 93 if ((da<db)||(da==db)&&(deep[a]<deep[b])) a^=b^=a^=b; 94 if (gf[a]==gf[b]) 95 { 96 vec.pb(mp(id[b],id[a])); 97 break; 98 } 99 else 100 { 101 vec.pb(mp(id[gf[a]],id[a])); 102 a=f[gf[a]]; 103 } 104 } 105 sort(vec.begin(),vec.end()); 106 int head=0; 107 for (int i=0;i<vec.size();i++) 108 { 109 if (head!=vec[i].fi-1) 110 change(1,head,vec[i].fi-1,c); 111 head=vec[i].sc; 112 } 113 if (head!=n) change(1,head,n,c); 114 } 115 int main() 116 { 117 scanf("%d%d",&n,&m); 118 for (i=1;i<n;i++) 119 { 120 scanf("%d%d",&a,&b); 121 link(a,b);link(b,a); 122 } 123 dfs1(1,0); 124 dfs2(1,0,1); 125 126 build(1,0,n); 127 for (i=1;i<=m;i++) 128 { 129 scanf("%d%",&q[i].typ); 130 if (q[i].typ==2) 131 { 132 scanf("%d",&q[i].w); 133 int tmp=id[q[i].w]; 134 printf("%d\n",query(1,tmp-1,tmp)); 135 } 136 else 137 if (q[i].typ==0) 138 { 139 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].w); 140 gao(q[i].l,q[i].r,q[i].w); 141 } 142 else 143 { 144 scanf("%d",&q[i].w); 145 int tmp=q[i].w; 146 gao(q[tmp].l,q[tmp].r,-q[tmp].w); 147 } 148 } 149 150 }