2018沈阳网络赛J

给一颗树,两种操作,一种把同一层的点权值加上v,另一种求一点下的子树权值和。

按层数中点个数分块,小块直接暴力把所有点用bit更新,大块把层的值存下来。

询问的时候子树权值和为bit中的值以及其下面的点在大块中的值,下面中的点在大块中的值用二分实现。

#include <bits/stdc++.h>
#include <unordered_set>
#include <unordered_map>
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define rep(i,x,y) for(i=x;i<=y;i++)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define up rt,rt<<1,rt<<1|1
#define mem(x) memset(x,0,sizeof(x))
#define mem1(x) memset(x,-1,sizeof(x))
#define LMissher
using namespace std;
typedef long long ll;
typedef double db;
const int M = 1e5+7;
const double pi = acos(-1);
const int inf = 2147483647;
const int mod = 1e9+7;

int n,q,i;
int cnt,head[M],tot,dep;
vector<int> d[M];
vector<int> lg;
int in[M],out[M];
ll ans[M],c[M];
void init(){
    tot=cnt=0;
    mem1(head);
}
struct edge
{
    int v,nex;
}e[M<<1];
void add(int u,int v){
    e[++cnt].v=v;e[cnt].nex=head[u];
    head[u]=cnt;
}
void dfs(int u,int fa,int de){
    dep=max(de,dep);
    in[u]=++tot;
    d[de].pb(in[u]);
    for(int j=head[u];~j;j=e[j].nex){
        int v=e[j].v;
        if(v==fa) continue;
        dfs(v,u,de+1);
    }
    out[u]=tot;
}
void update(int x,ll v){
    for(;x<=n;x+=x&(-x)){
        c[x]+=v;
    }
}
ll query(int x){
    ll tmp=0;
    for(;x;x-=x&(-x)) tmp+=c[x];
    return tmp;
}
int main(){
    #ifdef LMissher
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
    #endif
    init();
    scanf("%d%d",&n,&q);
    rep(i,1,n-1){
        int from,to;
        scanf("%d%d",&from,&to);
        add(from,to);add(to,from);
    }
    dep=0;
    dfs(1,-1,0);
    int block=1<<12;
    rep(i,0,dep){
        if(d[i].size()>block) lg.pb(i);
    }
    int op,l,v,rt;
    while(q--){
        scanf("%d",&op);
        if(op==1){
            scanf("%d%d",&l,&v);
            if(d[l].size()>block) ans[l]+=1ll*v;
            else{
                for(i=0;i<d[l].size();i++){
                    update(d[l][i],v*1ll);
                }
            }
        }
        else{
            scanf("%d",&rt);
            ll aa=query(out[rt])-query(in[rt]-1);
            for(i=0;i<lg.size();i++){
                aa+=(upper_bound(d[lg[i]].begin(),d[lg[i]].end(),out[rt])-lower_bound(d[lg[i]].begin(),d[lg[i]].end(),in[rt]))*ans[lg[i]];
            }
            printf("%lld\n",aa);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/LMissher/p/9611076.html

时间: 2024-09-28 12:12:52

2018沈阳网络赛J的相关文章

2018 徐州网络赛 J

131072K After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N \times MN×M little squares. That is to say, the height of the rectangle is NN and the width of the

2018沈阳网络赛G

容斥+状压 #include<bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD = 1e9+7; #include<vector> //const int MAX = 110; const int N = 100000; int arr[6000000];//p[N]用来存质数 ll n; int p; vector<ll>v; void getp(ll m, ll n) { /

2018焦作网络赛J

不知道题意,队友用java大数+二分过了? import java.util.Arrays; import java.util.Scanner; import java.io.*; import java.math.*; public class Main { static boolean check(BigInteger num,BigInteger n) { boolean flag = true; BigInteger a = new BigInteger("0"); BigIn

ICPC 2018 南京网络赛 J Magical Girl Haze(多层图最短路)

传送门:https://nanti.jisuanke.com/t/A1958 题意:n个点m条边的路,你有k次机会将某条路上的边权变为0,问你最短路径长度 题解:最短路变形,我们需要在常规的最短路上多开 一维,记录,我消耗j次机会时的最短路径长度为多少 代码: /** * ┏┓ ┏┓ * ┏┛┗━━━━━━━┛┗━━━┓ * ┃ ┃ * ┃ ━ ┃ * ┃ > < ┃ * ┃ ┃ * ┃... ⌒ ... ┃ * ┃ ┃ * ┗━┓ ┏━┛ * ┃ ┃ Code is far away fro

[ACM-ICPC 2018 沈阳网络赛] G. Spare Tire (思维+容斥)

A sequence of integer \lbrace a_n \rbrace{an?} can be expressed as: \displaystyle a_n = \left\{ \begin{array}{lr} 0, & n=0\\ 2, & n=1\\ \frac{3a_{n-1}-a_{n-2}}{2}+n+1, & n>1 \end{array} \right.an?=????0,2,23an−1?−an−2??+n+1,?n=0n=1n>1? N

[ACM-ICPC 2018 沈阳网络赛] Ka Chang (dfs序+树状数组+分块)

Given a rooted tree ( the root is node 11 ) of NN nodes. Initially, each node has zero point. Then, you need to handle QQ operations. There're two types: 1\ L\ X1 L X: Increase points by XX of all nodes whose depth equals LL ( the depth of the root i

2018 CCPC网络赛

2018 CCPC网络赛 Buy and Resell 题目描述:有一种物品,在\(n\)个地点的价格为\(a_i\),现在一次经过这\(n\)个地点,在每个地点可以买一个这样的物品,也可以卖出一个物品,问最终赚的钱的最大值. solution 用两个堆来维护,一个堆维护已经找到卖家的,一个堆维护还没找到卖家的. 对于第\(i\)个地点,在已经找到卖家的堆里找出卖的钱的最小值,如果最小值小于\(a_i\),则将卖家换成\(i\),然后将原来的卖家放到没找到卖家的那里:如果最小值对于\(a_i\)

2019ACM-ICPC沈阳网络赛-C-Dawn-K&#39;s water(完全背包模板题)

Dawn-K's water  1000ms 262144K Dawn-K recently discovered a very magical phenomenon in the supermarket of Northeastern University: The large package is not necessarily more expensive than the small package. On this day, Dawn-K came to the supermarket

2015沈阳网络赛1003 Minimum Cut 树链剖分 数组维护前缀和进行区间增减

2015沈阳网络赛1003  Minimum Cut   树链剖分 数组维护前缀和进行区间增减 Minimum Cut Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Given a simple unweighted graph G