[HNOI 2015]開店
阿新 • • 發佈:2018-08-04
ons bits 1+n odi lse urn dep inline 題意
題意:求“方便值”
思路:樹鏈剖分維護修改即可,似乎還有點分樹的做法~
#include<bits/stdc++.h> #define int long long #define debug(x) cout<<"debug:"<<x<<endl using namespace std; inline int read(){ int q=0,f=1;char ch=getchar(); while(!isdigit(ch)){ if(ch==‘-‘) f=-1;ch = getchar(); } while(isdigit(ch)){ q=q*10+ch-‘0‘;ch=getchar(); } return q*f; } const int maxn = 300010*2; const int inf = 0x3f3f3f3f; int n,m; int cnt; int idx; int rt[maxn]; int size; int ans; int head[maxn]; int nxt[maxn]; int ver[maxn]; int w[maxn]; int siz[maxn]; int fa[maxn]; int top[maxn]; int dfn[maxn]; int Last[maxn]; int root; inline void add(int u,int v,int wi){ ver[++cnt] = v; nxt[cnt] = head[u];head[u] = cnt; w[cnt] = wi; return; } struct node { int v; int id; }a[maxn]; inline bool operator < (node l,node r){ return l.v == r.v ? l.id < r.id:l.v < r.v; } int dep[maxn]; int Dep[maxn]; #define travel(x) for(int i = head[x];i;i=nxt[i]) inline void dfs1(int x,int f){ siz[x] = 1; fa[x] = f; travel(x){ int y = ver[i]; if(y != f){ dep[y] = dep[x] + w[i]; Last[y] = w[i]; dfs1(y,x); siz[x] += siz[y]; } } } int E[maxn]; inline void dfs2(int x,int f){ dfn[x] = ++idx; E[dfn[x]] = Last[x]; int mx = 0; int tmp = 0; travel(x){ int y = ver[i]; if(y != f && siz[y] > mx){ tmp = y; mx = siz[y]; } } if(!tmp) return; top[tmp] = top[x]; dfs2(tmp,x); travel(x){ int y = ver[i]; if(y != f && y != tmp){ top[y] = y; dfs2(y,x); } } } const int maxm = 8e6+10; int ls[maxm]; int rs[maxm]; int sum[maxm]; int tot[maxm]; inline void modify(int l,int r,int L,int R,int &p,int v){ p = ++size; ls[p] = ls[v]; rs[p] = rs[v]; sum[p] = sum[v]; tot[p] = tot[v]; if(l == L && r == R){ ++tot[p]; return; } sum[p] += E[r] - E[l - 1]; int mid = (L + R) >> 1; if(r <= mid){ modify(l,r,L,mid,ls[p],ls[v]); } else if(mid +1 <= l){ modify(l,r,mid+1,R,rs[p],rs[v]); } else { modify(l,mid,L,mid,ls[p],ls[v]); modify(mid+1,r,mid+1,R,rs[p],rs[v]); } } inline int get_ans(int l,int r,int L,int R,int p){ int res = (E[r] - E[l - 1])*tot[p]; if(l == L && r == R){ return res + sum[p]; } int mid = (L + R) >> 1; if(r <= mid){ return res + get_ans(l,r,L,mid,ls[p]); } else if(mid + 1 <= l){ return res + get_ans(l,r,mid+1,R,rs[p]); } else{ return res + get_ans(l,mid,L,mid,ls[p]) + get_ans(mid+1,r,mid+1,R,rs[p]); } } inline int get_rt(int p){ while(p){ modify(dfn[top[p]],dfn[p],1,n,root,root); p = fa[top[p]]; } return root; } inline int query(int Rt,int p){ int res = 0; while(p){ res += get_ans(dfn[top[p]],dfn[p],1,n,Rt); //debug(res); p = fa[top[p]]; } return res; } int A; inline void solve() { int x,y,z; n = read(),m = read(),A = read(); for(int i = 1;i <= n; ++i){ a[i].v = read(); a[i].id = i; } sort(a+1,a+n+1); for(int i = 1;i < n; ++i){ x = read(),y = read(),z = read(); add(x,y,z); add(y,x,z); } dfs1(1,0),top[1] = 1; dfs2(1,0); for(int i = 1;i <= n; ++i){ E[i] += E[i - 1]; Dep[i] = Dep[i - 1] + dep[a[i].id]; ///debug(Dep[i]); } for(int i = 1;i <= n; ++i){ rt[i] = get_rt(a[i].id); //debug(rt[i]); } // for(int i = 1;i <= n; ++i) // { // debug(a[i].v); // debug(a[i].id); // } //debug(ans); while(m--){ z = read(),x = read(),y = read(); // debug(x); // debug(y); x = (1ll * x + ans)%A; y = (1ll * y + ans) % A; // debug(x); // debug(y); if(x > y){ swap(x,y); } x=lower_bound(a+1,a+1+n,(node){x,0})- a; y=upper_bound(a+1,a+1+n,(node){y,inf})-a-1; ans = (y - x + 1)*dep[z]+Dep[y] - Dep[x - 1]; //debug(ans); ans -= 2ll*(query(rt[y],z) - query(rt[x - 1],z)); //debug(ans); printf("%lld\n",ans); } return; } signed main(){solve();return 0;}
[HNOI 2015]開店