• [JLOI2014]松鼠的新家-树链剖分


    最开始的时候我在写线段树部分的时候还打了一个build,后来一想,打个球球大作战的build啊!!!有个锤子的用啊!!!

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 3e6+5;
      4 int n;
      5 int e,begin[maxn],next[maxn],to[maxn],a[maxn];
      6 int tree[maxn<<2],lazy[maxn<<2];
      7 int son[maxn],father[maxn],id[maxn],cnt,deep[maxn],size[maxn],top[maxn];
      8 int res;
      9 inline int read(){
     10    int s=0,w=1;
     11    char ch=getchar();
     12    while(ch<='0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
     13    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
     14    return s*w;
     15 }
     16 inline void add(int x,int y){
     17     to[++e] = y;
     18     next[e] = begin[x];
     19     begin[x] = e;
     20 }
     21 inline void pushup(int root){
     22     tree[root] = tree[root<<1]+tree[root<<1|1];
     23 }
     24 inline void pushdown(int root,int pos){
     25     lazy[root<<1] += lazy[root];
     26     lazy[root<<1|1] += lazy[root];
     27     tree[root<<1] += lazy[root]*(pos-(pos>>1));
     28     tree[root<<1|1] += lazy[root]*(pos>>1);
     29     lazy[root] = 0;
     30 }
     31 inline void query(int root,int l,int r,int al,int ar){
     32     if(al <= l && ar >= r){
     33         res += tree[root]; 
     34         return;
     35     }
     36     if(lazy[root])pushdown(root,r-l+1);
     37     int mid = l+r>>1;
     38     if(al <= mid)query(root<<1,l,mid,al,ar);
     39     if(ar > mid)query(root<<1|1,mid+1,r,al,ar);
     40 }
     41 inline void update(int root,int l,int r,int al,int ar,int k){
     42     if(al <= l && ar >= r){
     43         lazy[root] += k;
     44         tree[root] += k*(r-l+1);
     45         return;
     46     }
     47     if(lazy[root])pushdown(root,r-l+1);
     48     int mid = l+r>>1;
     49     if(al <= mid)update(root<<1,l,mid,al,ar,k);
     50     if(ar > mid)update(root<<1|1,mid+1,r,al,ar,k);
     51     pushup(root);
     52 }
     53 inline void update_range(int x,int y,int k){
     54     while(top[x] != top[y]){
     55         if(deep[top[x]] < deep[top[y]])swap(x,y);
     56         update(1,1,n,id[top[x]],id[x],k);
     57         x = father[top[x]];
     58     }
     59     if(deep[x] > deep[y])swap(x,y);
     60     update(1,1,n,id[x],id[y],k);
     61 }
     62 inline void dfs1(int x,int fa,int dep){
     63     deep[x] = dep;
     64     father[x] = fa;
     65     size[x] = 1;
     66     int maxson = -1;
     67     for(int i = begin[x];i;i = next[i]){
     68         int y = to[i];
     69         if(y == fa)continue;
     70         dfs1(y,x,dep+1);
     71         size[x] += size[y];
     72         if(size[y] > maxson)son[x] = y,maxson = size[y];
     73     }
     74 }
     75 inline void dfs2(int x,int topf){
     76     id[x] = ++cnt;
     77     top[x] = topf;
     78     if(!son[x])return;
     79     dfs2(son[x],topf);
     80     for(int i = begin[x];i;i = next[i]){
     81         int y = to[i];
     82         if(y == father[x] || y == son[x])continue;
     83         dfs2(y,y);
     84     }
     85 }
     86 int main(){
     87     n = read();
     88     for(int i = 1;i <= n;i++)a[i] = read();
     89     for(int i = 1,x,y;i < n;i++){
     90         x = read();
     91         y = read();
     92         add(x,y);
     93         add(y,x);
     94     }
     95     dfs1(1,0,1);
     96     dfs2(1,1);
     97     for(int i = 1;i < n;i++){
     98         update_range(a[i],a[i+1],1);
     99         update_range(a[i+1],a[i+1],-1);
    100     }
    101     for(int i = 1;i <= n;i++)res = 0,query(1,1,n,id[i],id[i]),printf("%d
    ",res);
    102     return 0;
    103 }
  • 相关阅读:
    234树(2)实现
    矩阵的坐标变换(转)
    OpenGL 学习笔记(3)绘制几何物体
    OpenGL 学习笔记(1)初始化窗体
    OpenGL学习笔记(5)3D基本概念
    矩阵的三维变换(转)
    OpenGL 学习笔记(2)创建第一个图形
    234树(1)概念
    OpenGL 学习笔记(4)顶点数组
    OpenGL学习笔记(6)第一个动画
  • 原文地址:https://www.cnblogs.com/wangyifan124/p/10312332.html
Copyright © 2020-2023  润新知