zoukankan      html  css  js  c++  java
  • Partition(线段树的离线处理)

    有一点类似区间K值的求法。

    这里有两颗树,一个是自己建的线段树,一个是题目中给定的树。以线段树和树进行区分。

    首先离散化一下,以离散化后的结果建线段树,线段树的节点开了2维,一维保存当前以当前节点为权值的树的节点是往左走的,另一维是往右走的,用一个vector保存一下以当前i节点为结束的询问,因为所有的询问都是从根节点出发的,只需保存终点即可。

    然后从根节点出发遍历整棵树,当走到当前节点时,枚举以当前节点的询问q[i],然后求出比q[i].x大的向左和向右走的节点个数,以及比它小的个数,如果有相等的直接为0,最后根据可能性加起来即可。

    每走完一个节点,回退时,把当前节点更新为未走。

    把树节点的权值跟询问的搞混了,WA一次。。搞了组数据才看出来

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<map>
     11 using namespace std;
     12 #define N 100010
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 #pragma comment(linker, "/STACK:1024000000,1024000000")
     19 int s[N<<2][2],a[N<<1],b[N];
     20 map<int,int>f;
     21 vector<int>ed[N];//儿子
     22 vector<int>dd[N];//以i节点结束的询问
     23 int g ;
     24 struct node{
     25     int v,x;
     26     int ax,ay,f;
     27 }p[N];
     28 void up(int w)
     29 {
     30     s[w][0] = s[w<<1][0]+s[w<<1|1][0];//向左走
     31     s[w][1] = s[w<<1][1]+s[w<<1|1][1];//向右走
     32 }
     33 void build(int l,int r,int w)
     34 {
     35     if(l==r)
     36     {
     37         s[w][0] = s[w][1] = 0;
     38         return ;
     39     }
     40     int m = (l+r)>>1;
     41     build(l,m,w<<1);
     42     build(m+1,r,w<<1|1);
     43     up(w);
     44 }
     45 void update(int p,int d,int dir,int l,int r,int w)
     46 {
     47     if(l==r)
     48     {
     49         s[w][dir] += d;
     50         return ;
     51     }
     52     int m = (l+r)>>1;
     53     if(p<=m) update(p,d,dir,l,m,w<<1);
     54     else update(p,d,dir,m+1,r,w<<1|1);
     55     up(w);
     56 }
     57 int query(int a,int b,int dir,int l,int r,int w)
     58 {
     59     if(a<=l&&b>=r)
     60     {
     61         return s[w][dir];
     62     }
     63     int m = (l+r)>>1;
     64     int res=0;
     65     if(a<=m) res+=query(a,b,dir,l,m,w<<1);
     66     if(b>m) res+=query(a,b,dir,m+1,r,w<<1|1);
     67     return res;
     68 }
     69 void dfs(int u,int pre)
     70 {
     71     int i;
     72     for(i = 0; i < dd[u].size(); i++)
     73     {
     74         int k = dd[u][i];
     75         int id = f[p[k].x];
     76        // cout<<k<<endl;
     77         int cnt1 = query(id,id,0,1,g,1);
     78         int cnt2 = query(id,id,1,1,g,1);
     79         //cout<<cnt1<<" "<<cnt2<<" "<<u<<" "<<id<<endl;
     80         if(cnt1||cnt2)
     81         {
     82             p[k].f = 0;
     83             continue;
     84         }
     85         else
     86         {
     87             p[k].f = 1;
     88             int l0 = query(1,id,0,1,g,1);
     89             int l1 = query(1,id,1,1,g,1);
     90             int r0 = query(id,g,0,1,g,1);
     91             int r1 = query(id,g,1,1,g,1);
     92            // cout<<l0<<" "<<l1<<" "<<r0<<" "<<r1<<endl;
     93             p[k].ay = r0+r1+3*(l1+l0);
     94             p[k].ax = l1;
     95         }
     96     }
     97     for(i = 0;i < ed[u].size() ; i++)
     98     {
     99         int v = ed[u][i];
    100         int id = f[b[u]];
    101        // cout<<id<<" "<<u<<endl;
    102         if(i==0)
    103         {
    104             update(id,1,0,1,g,1);
    105         }
    106         else update(id,1,1,1,g,1);
    107         dfs(v,u);
    108         if(i==0)
    109         update(id,-1,0,1,g,1);
    110         else update(id,-1,1,1,g,1);
    111     }
    112 }
    113 int main()
    114 {
    115     int t,i,n,m,q;
    116     cin>>t;
    117     while(t--)
    118     {
    119         scanf("%d",&n);
    120         f.clear();
    121         g = 0;
    122         for(i = 1; i <=n; i++)
    123         {
    124             scanf("%d",&a[i]);
    125             b[i] = a[i];
    126             ed[i].clear();
    127             dd[i].clear();
    128         }
    129         scanf("%d",&m);
    130         for(i = 1; i <= m; i++)
    131         {
    132             int u,l,r;
    133             scanf("%d%d%d",&u,&l,&r);
    134             ed[u].push_back(l);
    135             ed[u].push_back(r);
    136         }
    137         scanf("%d",&q);
    138         for(i = 1;i <= q ;i++)
    139         {
    140             scanf("%d%d",&p[i].v,&p[i].x);
    141             dd[p[i].v].push_back(i);
    142             a[n+i] = p[i].x;
    143         }
    144         sort(a+1,a+n+q+1);
    145         f[a[1]] = ++g;
    146         for(i = 2; i <= n+q ; i++)
    147         {
    148             if(a[i]!=a[i-1])
    149             f[a[i]] = ++g;
    150         }
    151         build(1,g,1);
    152         dfs(1,-1);
    153         for(i = 1; i <= q;  i++)
    154         {
    155             if(p[i].f==0)
    156             printf("%d
    ",0);
    157             else
    158             printf("%d %d
    ",p[i].ax,p[i].ay);
    159         }
    160     }
    161     return 0;
    162 }
    View Code
  • 相关阅读:
    form表格属性
    sql查询练习题
    在Mac上搭建java开发环境
    搭建vim作为java开发环境(-)
    C++学习之class
    nginx学习----1
    Html5学习笔记---1
    国庆节
    memcache------01
    jquery学习之概述
  • 原文地址:https://www.cnblogs.com/shangyu/p/3764402.html
Copyright © 2011-2022 走看看