zoukankan      html  css  js  c++  java
  • BSOJ1470&BZOJ4372 烁烁的游戏

    题目

    BSOJ1470&BZOJ4372 烁烁的游戏

    分析

    点分树+线段树

    首先我们可以发现,这个和模板题的区别就是那里是单点修改区间查询,但是这里是区间修改单点查询。

    于是在线段树上把这两个操作的对应区间反过来就好了。

    具体可以见代码。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define M 100010
    #define ls ch[node][0]
    #define rs ch[node][1]
    using namespace std;
    int read() {
        char ch=getchar();int x=0;
        while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    int n,m,num,cnt,root,S;
    int sz[M],size[M],top[M],fa[M],deep[M],son[M],head[M],maxn[M],f[M];
    int rt1[M],rt2[M],val[M<<7],ch[M<<7][2];bool vis[M];
    struct point{int next,to;}e[M<<1];
    void add(int from,int to) {
        e[++num].next=head[from];
        e[num].to=to;
        head[from]=num;
    }
    void dfs1(int x) {
        sz[x]=1;deep[x]=deep[fa[x]]+1;
        for(int i=head[x];i;i=e[i].next) {
            int to=e[i].to;
            if(fa[x]==to) continue;
            fa[to]=x,dfs1(to),sz[x]+=sz[to];
            if(sz[to]>sz[son[x]]) son[x]=to;
        }
    }
    void dfs2(int x,int tp) {
        top[x]=tp;
        if(son[x]) dfs2(son[x],tp);
        for(int i=head[x];i;i=e[i].next)
            if(e[i].to!=son[x]&&e[i].to!=fa[x])
                dfs2(e[i].to,e[i].to);
    }
    int lca(int x,int y) {
        while(top[x]!=top[y]) {
            if(deep[top[x]]<deep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        return deep[x]>deep[y]?y:x;
    }
    int dis(int x,int y) {
        return deep[x]+deep[y]-2*deep[lca(x,y)];
    }
    void getroot(int x,int fa) {
        size[x]=1;maxn[x]=0;
        for(int i=head[x];i;i=e[i].next) {
            int to=e[i].to;
            if(to==fa||vis[to]) continue;
            getroot(to,x);
            size[x]+=size[to];
            maxn[x]=max(maxn[x],size[to]);
        }
        maxn[x]=max(maxn[x],S-size[x]);
        if(maxn[x]<maxn[root]) root=x;
    }
    void solve(int x,int fa) {
        vis[x]=true;f[x]=fa;
        for(int i=head[x];i;i=e[i].next) {
            int to=e[i].to;
            if(vis[to]) continue;
            root=0,S=size[to],getroot(to,0);
            solve(root,x);
        }
    }
    void change(int &node,int l,int r,int l1,int r1,int v) {
        if(!node) node=++cnt;
        if(l1<=l&&r1>=r) {
            val[node]+=v;return;
        }
        int mid=(l+r)/2;
        if(l1<=mid) change(ls,l,mid,l1,r1,v);
        if(r1>mid) change(rs,mid+1,r,l1,r1,v);
    }
    int query(int node,int l,int r,int x) {
        if(!node) return 0;
        if(l==r) return val[node];
        int mid=(l+r)/2;
        if(x<=mid) return val[node]+query(ls,l,mid,x);
        else return val[node]+query(rs,mid+1,r,x);
    }
    void update(int x,int d,int v) {
        change(rt1[x],0,n,0,d,v);
        for(int i=x;f[i];i=f[i]) {
            int dt=dis(x,f[i]);
            if(dt>d) continue;
            change(rt1[f[i]],0,n,0,d-dt,v);
            change(rt2[i],0,n,0,d-dt,v);
        }
    }
    int ask(int x) {
        int res=query(rt1[x],0,n,0);
        for(int i=x;f[i];i=f[i]) {
            int dt=dis(x,f[i]);
            res+=query(rt1[f[i]],0,n,dt)-query(rt2[i],0,n,dt);
        }
        return res;
    }
    int main() {
        n=read();m=read();
        for(int i=1;i<n;i++) {
            int u=read(),v=read();
            add(u,v),add(v,u);
        }
        dfs1(1),dfs2(1,1);
        maxn[0]=S=n;
        getroot(1,0),solve(root,0);
        for(int i=1;i<=m;i++) {
            char s[10];scanf("%s",s);
            if(s[0]=='M') {
                int x=read(),d=read(),w=read();
                update(x,d,w);
            }
            else {
                int x=read();
                printf("%d
    ",ask(x));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14757988.html
Copyright © 2011-2022 走看看