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
",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 } 
原文地址:https://www.cnblogs.com/fzmh/p/5414273.html