• bzoj 3307 雨天的尾巴


    题目链接:传送门

    题目大意:中文题,略

    题目思路:网上有题解说是合并线段树的,但是太难蒟蒻不会,只能用树剖求解

         如果不是树而是一维数组我们会怎么解?     

         当然是利用前缀和思想标记 (L) v+1,(R+1) v-1,然后扫一遍

         用线段树取最大复杂度 nlogn

         现在是搬到了树上,怎么做?

         利用树链剖分拆成链然后在像一维那样做就行,复杂度n(logn)^2

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <stack>
      8 #include <cctype>
      9 #include <queue>
     10 #include <string>
     11 #include <vector>
     12 #include <set>
     13 #include <map>
     14 #include <climits>
     15 #define lson rt<<1,l,mid
     16 #define rson rt<<1|1,mid+1,r
     17 #define fi first
     18 #define se second
     19 #define ping(x,y) ((x-y)*(x-y))
     20 #define mst(x,y) memset(x,y,sizeof(x))
     21 #define mcp(x,y) memcpy(x,y,sizeof(y))
     22 using namespace std;
     23 #define gamma 0.5772156649015328606065120
     24 #define MOD 1000000007
     25 #define inf 0x3f3f3f3f
     26 #define N 100005
     27 #define maxn 30010
     28 typedef pair<int,int> PII;
     29 typedef long long LL;
     30 LL read(){
     31     LL x=0,f=1;char ch=getchar();
     32     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     33     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     34     return x*f;
     35 }
     36 vector<int>V[N];
     37 map<int,int>M;
     38 int num[N],ncnt,head[N],hcnt,ans[N];
     39 int n,m,k,L,R,sz,v;
     40 int son[N],siz[N],id[N],tid;
     41 int top[N],dep[N],fa[N],posi[N];
     42 struct Node{int to,nxt,v;}node[N<<3];
     43 struct Seg{int v,va;}seg[N<<2];
     44 inline void add(int x,int y,int v){
     45     node[hcnt].to=y,node[hcnt].nxt=head[x],node[hcnt].v=v,head[x]=hcnt++;
     46 }
     47 void dfs1(int u,int f,int deep){
     48     fa[u]=f,++siz[u],dep[u]=deep;
     49     for(int e:V[u]){
     50         if(e==f)continue;
     51         dfs1(e,u,deep+1);siz[u]+=siz[e];
     52         if(!son[u]||siz[son[u]]<siz[e])son[u]=e;
     53     }
     54 }
     55 void dfs2(int u,int tp){
     56     id[u]=++tid,posi[tid]=u,top[u]=tp;
     57     if(!son[u])return; dfs2(son[u],tp);
     58     for(int e:V[u])if(!id[e])dfs2(e,e);
     59 }
     60 void pushup(int rt){
     61     if(seg[rt<<1].v>seg[rt<<1|1].v)seg[rt]=seg[rt<<1];
     62     else if(seg[rt<<1].v<seg[rt<<1|1].v)seg[rt]=seg[rt<<1|1];
     63     else if(num[seg[rt<<1].va]<num[seg[rt<<1|1].va])seg[rt]=seg[rt<<1];
     64     else seg[rt]=seg[rt<<1|1];
     65 }
     66 void update(int rt,int l,int r){
     67     if(l==r){seg[rt].v+=v;seg[rt].va=l;return;}
     68     int mid=l+r>>1;
     69     if(L<=mid)update(lson);
     70     else update(rson);
     71     pushup(rt);
     72 }
     73 void build(int rt,int l,int r){
     74     if(l==r){seg[rt].va=l;return;}
     75     int mid=l+r>>1;
     76     build(lson);build(rson);
     77 }
     78 int main(){
     79     int i,j,group,x,y,Case=0;
     80     n=read(),m=read();
     81     mst(head,-1);
     82     for(i=1;i<n;++i){
     83         x=read(),y=read();
     84         V[x].push_back(y);
     85         V[y].push_back(x);
     86     }
     87     dfs1(1,1,1);dfs2(1,1);
     88     for(i=1;i<=m;++i){
     89         x=read(),y=read();v=read();
     90         if(!M[v]){
     91             M[v]=++ncnt;
     92             num[ncnt]=v;
     93         }
     94         v=M[v];
     95         while(top[x]!=top[y]){
     96             if(dep[top[x]]<dep[top[y]])swap(x,y);
     97             L=id[top[x]],R=id[x];
     98             add(L,v,1);add(R+1,v,-1);
     99             x=fa[top[x]];
    100         }
    101         if(dep[x]<dep[y])swap(x,y);
    102         L=id[y],R=id[x];
    103         add(L,v,1);add(R+1,v,-1);
    104     }
    105     build(1,1,m);
    106     for(i=1;i<=n;++i){
    107         for(j=head[i];~j;j=node[j].nxt){
    108             L=node[j].to;v=node[j].v;
    109             update(1,1,m);
    110         }
    111         ans[posi[i]]=num[seg[1].va];
    112     }
    113     for(i=1;i<=n;++i)printf("%d
    ",ans[i]);
    114     return 0;
    115 }

     

  • 相关阅读:
    C#获取本地IP地址
    C#中将字符串转换成数值
    JavaScript实现基于对象的双端队列
    Java网络编程
    JavaScript实现基于对象的队列
    JavaScript实现基于对象的栈
    JavaScript实现基于数组的栈
    发送短信按钮倒计时案例
    JavaScript动态显示时间
    html
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5933544.html
Copyright © 2020-2023  润新知