HNOI2015开店

来源:互联网 发布:此谓知本 此谓知之至也 编辑:程序博客网 时间:2024/04/16 12:54

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=4012


题解

这里写图片描述


代码

#include <cstdio>#include <cstring>#include <algorithm>#define REP(i, l, r) for(int i=(l); i!=(r); ++i)#define FOR(i, l, r) for(int i=(l); i<=(r); ++i)#define DRP(i, l, r) for(int i=(l); i!=(r); --i)#define DFR(i, l, r) for(int i=(l), i>=(r); --i)typedef long long LL;template<class T>T Min(const T &a, const T &b) {return a < b ? a : b;}template<class T>T Max(const T &a, const T &b) {return a > b ? a : b;}template<class T>bool Chkmin(T &a, const T &b) {return a > b ? a=b, 1 : 0;}template<class T>bool Chkmax(T &a, const T &b) {return a < b ? a=b, 1 : 0;}const int SN = 150000 + 47;const int SM = SN << 1 | 1;const int ST = 10000000 + 47;int head[SN], nxt[SM], to[SM], wei[SM], tot;int size[SN], fa[SN], deep[SN], son[SN], val[SN], dis[SN];int top[SN], f[SN], g[SN], rnk;int a[SN], b[SN], c[SN], sum[SN], n, m, p;int rt[ST], lson[ST], rson[ST], data[ST], cnt;LL segs[ST], sd[SN], lstans;void NxtInt(int &);bool Cmp(const int &, const int &);void Add(int, int, int);void DFS(int);void DFS(int, int);void Get(int);int Modify(int, int, int, int, int);void Query(int, int, int);LL Query(int, int, int, int, int, int);int main() {    freopen("shop.in", "r", stdin);    freopen("shop.out", "w", stdout);    int x, y, z, r, s;    NxtInt(n), NxtInt(m), NxtInt(p);    FOR(i, 1, n) NxtInt(a[i]), b[i] = i;    std::sort(b+1, b+n+1, Cmp);    FOR(i, 1, n) c[b[i]] = i;    std::sort(a+1, a+n+1);    REP(i, 1, n) NxtInt(x), NxtInt(y), NxtInt(z), Add(c[x], c[y], z);    deep[1]=1, DFS(1), DFS(1, 1);    FOR(i, 1, n) sum[i] = sum[i-1]+val[i];    FOR(i, 1, n) sd[i] = sd[i-1]+dis[i];    FOR(i, 1, n) Get(i);    while(m--) {        NxtInt(x), NxtInt(y), NxtInt(z);        y = (y+lstans)%p, z = (z+lstans)%p;        if(Min(y, z)>a[n] || Max(y, z)<a[0]) {puts("0"), lstans = 0; continue;}        r = std::lower_bound(a+1, a+n+1, Min(y, z)) - a;        s = std::upper_bound(a+1, a+n+1, Max(y, z)) - a - 1;        Query(r, s, c[x]);        printf("%lld\n", lstans=sd[s]-sd[r-1]+1LL*(s-r+1)*dis[c[x]]-2*lstans);    }    return 0;}void NxtInt(int &in) {    char ch;    for(ch=getchar(); ch>'9'||ch<'0'; ch=getchar()) ;    for(in=0; ch>='0'&&ch<='9'; ch=getchar()) in=in*10+ch-'0';}bool Cmp(const int &x, const int &y) {    return a[x] < a[y];}void Add(int u, int v, int w) {    nxt[++tot]=head[u]; head[u]=tot; to[tot]=v; wei[tot]=w;    nxt[++tot]=head[v]; head[v]=tot; to[tot]=u; wei[tot]=w;}void DFS(int u) {    size[u] = 1;    for(int i=head[u]; i; i=nxt[i])        if(to[i] != fa[u]) {            deep[to[i]]=deep[u]+1, fa[to[i]] = u;            val[to[i]]=wei[i], dis[to[i]]=dis[u]+wei[i];            DFS(to[i]), size[u]+=size[to[i]];            if(size[to[i]]>size[son[u]]) son[u] = to[i];        }}void DFS(int u, int v) {    top[u] = v, g[f[u]=++rnk] = u;    if(son[u]) DFS(son[u], v);    for(int i=head[u]; i; i=nxt[i])        if(to[i]!=son[u] && to[i]!=fa[u])            DFS(to[i], to[i]);}void Get(int x) {    int y = x;    rt[x] = rt[x-1];    while(top[y] != 1)        rt[x] = Modify(rt[x], 1, n, f[top[y]], f[y]), y = fa[top[y]];    if(y != 1) rt[x] = Modify(rt[x], 1, n, 1, f[y]);}int Modify(int rt, int l, int r, int L, int R) {    int x = ++cnt, mid = l+r>>1;    if(l==L && r==R) {        lson[x] = lson[rt], rson[x] = rson[rt];        data[x]=data[rt]+1, segs[x]=segs[rt]+dis[g[r]]-dis[fa[g[l]]];        return x;    }    if(R <= mid) {        lson[x] = Modify(lson[rt], l, mid, L, R);        rson[x] = rson[rt];    }    else if(L > mid) {        lson[x] = lson[rt];        rson[x] = Modify(rson[rt], mid+1, r, L, R);    }    else {        lson[x] = Modify(lson[rt], l, mid, L, mid);        rson[x] = Modify(rson[rt], mid+1, r, mid+1, R);    }    data[x] = data[rt];    segs[x]=segs[lson[x]]+segs[rson[x]]+1LL*data[rt]*(dis[g[r]]-dis[fa[g[l]]]);    return x;}void Query(int x, int y, int z) {    lstans = 0;    while(top[z] != 1)        lstans += Query(rt[x-1], rt[y], 1, n, f[top[z]], f[z]), z = fa[top[z]];    if(z != 1) lstans += Query(rt[x-1], rt[y], 1, n, 1, f[z]);}LL Query(int rt1, int rt2, int l, int r, int L, int R) {    if(l==L && r==R) return segs[rt2]-segs[rt1];    int mid = l+r>>1;    LL x = 1LL * (data[rt2]-data[rt1]) * (dis[g[R]]-dis[fa[g[L]]]);    if(R <= mid) return Query(lson[rt1], lson[rt2], l, mid, L, R) + x;    else if(L > mid) return Query(rson[rt1], rson[rt2], mid+1, r, L, R) + x;    else return Query(lson[rt1], lson[rt2], l, mid, L, mid) +             Query(rson[rt1], rson[rt2], mid+1, r, mid+1, R) + x;}
0 0
原创粉丝点击