比较容易想到的做法是树链剖分,每个线段树节点维护一个集合,对于一个修改路径操作,我们可以将线段树上不包含操作路径的节点的区间全部都进行一次修改,这种区间个数是logn级别的,这样询问的复杂度是O(qlogn),修改的复杂度是O(q(logn^3)),居然给卡过了。。。
代码
1 #include2 #include 3 #include 4 #include 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 s[N]; 16 vector >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 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 >1; 82 if (a