zoukankan      html  css  js  c++  java
  • BZOJ 4154

        感觉这个题的思想还是很妙的,刚开始看这道题的时候大概会向一些树的算法比如树链剖分或是主席树维护深度之类的方向去想,但是我们考虑它实际上是一个二维数点的问题,由于是子树的修改,我们很自然的会想到用DFS序来搞,那么对于一个子树深度不超过定值的所有点就被包含在了一个矩形中,这样我们就可以用KD_tree来进行矩形的赋值,单点查询了,这个我不知道可不可以用树套树来做,如果哪位神犇会用树套树来搞的话,请留言指导一下蒟蒻。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define maxn 100005
      6 typedef long long LL;
      7 const int mo=1000000007;
      8 int pre[maxn],last[maxn],other[maxn];
      9 int st[maxn],en[maxn],dep[maxn];
     10 int n,m,q,l,T,tot,rt,cmp_d,now[2];
     11 LL ans;
     12 struct KD_tree
     13 {
     14     int ls,rs;
     15     int d[2],mn[2],mx[2];
     16     int col,lazy;
     17 }t[maxn];
     18  
     19 inline int read(void)
     20 {
     21     int x=0;
     22     char ch=getchar();
     23     while (ch>'9'||ch<'0') ch=getchar();
     24     while (ch>='0'&&ch<='9')
     25     {
     26         x=x*10+ch-'0';
     27         ch=getchar();
     28     }
     29     return x;
     30 }
     31  
     32 void connect(int x,int y)
     33 {
     34     l++;
     35     pre[l]=last[x];
     36     last[x]=l;
     37     other[l]=y;
     38 }
     39  
     40 void dfs(int u)
     41 {
     42     st[u]=++tot;
     43     for (int p=last[u];p;p=pre[p])
     44     {
     45         int v=other[p];
     46         dep[v]=dep[u]+1;
     47         dfs(v);
     48     }
     49     en[u]=tot;
     50 }
     51  
     52 inline bool cmp(KD_tree a,KD_tree b)
     53 {
     54     int x=a.d[cmp_d],y=b.d[cmp_d];
     55     return x<y||(x==y&&a.d[!cmp_d]<b.d[!cmp_d]);
     56 }
     57  
     58 void KD_update(int x)
     59 {
     60     int ls=t[x].ls;
     61     int rs=t[x].rs;
     62     if (ls) 
     63     {
     64         t[x].mn[0]=min(t[x].mn[0],t[ls].mn[0]);
     65         t[x].mx[0]=max(t[x].mx[0],t[ls].mx[0]);
     66         t[x].mn[1]=min(t[x].mn[1],t[ls].mn[1]);
     67         t[x].mx[1]=max(t[x].mx[1],t[ls].mx[1]);
     68     }
     69     if (rs)
     70     {
     71         t[x].mn[0]=min(t[x].mn[0],t[rs].mn[0]);
     72         t[x].mx[0]=max(t[x].mx[0],t[rs].mx[0]);
     73         t[x].mn[1]=min(t[x].mn[1],t[rs].mn[1]);
     74         t[x].mx[1]=max(t[x].mx[1],t[rs].mx[1]);
     75     }
     76 }
     77  
     78 int KD_build(int l,int r,int D)
     79 {
     80     int mid=(l+r)>>1;
     81     cmp_d=D;
     82     nth_element(t+l,t+mid,t+r+1,cmp);
     83     t[mid].mn[0]=t[mid].mx[0]=t[mid].d[0];
     84     t[mid].mn[1]=t[mid].mx[1]=t[mid].d[1];
     85     t[mid].col=1;t[mid].lazy=0;
     86     t[mid].ls=t[mid].rs=0;
     87     if (l<mid) t[mid].ls=KD_build(l,mid-1,D^1);
     88     if (r>mid) t[mid].rs=KD_build(mid+1,r,D^1);
     89     KD_update(mid);
     90     return mid;
     91 }
     92  
     93 inline void push_down(int x)
     94 {
     95     if (!t[x].lazy) return;
     96     int ls=t[x].ls,rs=t[x].rs;
     97     if (ls) t[ls].col=t[ls].lazy=t[x].lazy;
     98     if (rs) t[rs].col=t[rs].lazy=t[x].lazy;
     99     t[x].lazy=0;
    100 }
    101  
    102 int KD_ask(int x,int D)
    103 {
    104     if (t[x].d[0]==now[0]&&t[x].d[1]==now[1]) return t[x].col;
    105     push_down(x);
    106     if (now[D]<t[x].d[D]||(now[D]==t[x].d[D]&&now[!D]<t[x].d[!D]))
    107         return KD_ask(t[x].ls,D^1);
    108     else
    109         return KD_ask(t[x].rs,D^1);
    110 }
    111  
    112 inline pair<bool,bool> in(int x,int x1,int y1,int x2,int y2)
    113 {
    114     bool p1= t[x].mn[0]>=x1&&t[x].mx[0]<=x2&&t[x].mn[1]>=y1&&t[x].mx[1]<=y2;
    115     bool p2= t[x].d[0]>=x1&&t[x].d[0]<=x2&&t[x].d[1]>=y1&&t[x].d[1]<=y2;
    116     return make_pair(p1,p2);
    117 }
    118  
    119 inline bool out(int x,int x1,int y1,int x2,int y2)
    120 {
    121     return t[x].mx[0]<x1||t[x].mn[0]>x2||t[x].mx[1]<y1||t[x].mn[1]>y2;
    122 }
    123  
    124 void KD_add(int x,int x1,int y1,int x2,int y2,int c)
    125 {
    126     if (!x) return;
    127     push_down(x);
    128     if (in(x,x1,y1,x2,y2).first) 
    129     {
    130         t[x].col=t[x].lazy=c;
    131         return;
    132     }
    133     if (out(x,x1,y1,x2,y2)) return;
    134     if (in(x,x1,y1,x2,y2).second) t[x].col=c;
    135     KD_add(t[x].ls,x1,y1,x2,y2,c);
    136     KD_add(t[x].rs,x1,y1,x2,y2,c);
    137 }
    138  
    139 int main()
    140 {
    141     T=read();
    142     while (T--) 
    143     {
    144         memset(last,0,sizeof last);l=tot=0;
    145         n=read();m=read();q=read();
    146         for (int i=2;i<=n;i++)
    147         {
    148             int fa=read();
    149             connect(fa,i);
    150         }
    151         dfs(1);
    152         for (int i=1;i<=n;i++) t[i].d[0]=st[i],t[i].d[1]=dep[i];
    153         rt=KD_build(1,n,0);
    154         ans=0;
    155         for (int i=1;i<=q;i++) 
    156         {
    157             int x=read(),y=read(),c=read();
    158             if (c==0) 
    159             {
    160                 now[0]=st[x];now[1]=dep[x];
    161                 y=KD_ask(rt,0);
    162                 ans=(ans+(LL)y*i)%mo;
    163             }
    164             else
    165             {
    166                 int x1=st[x],y1=dep[x];
    167                 int x2=en[x],y2=dep[x]+y;
    168                 KD_add(rt,x1,y1,x2,y2,c);
    169             }
    170         }
    171         printf("%lld\n",ans);
    172     }
    173     return 0;
    174 }
  • 相关阅读:
    如何让一个浮动垂直居中:两种方式!带来效果~~~~~~
    rgba()和opacity之间的区别(面试题)
    常用浏览器内核!IE,Chrome ,Firefox,Safari,Opera 等内核
    有关Option.inSamplSize 和 Compress 图片压缩
    Android App 启动 Activity 创建解析
     (转)windows一台电脑添加多个git账号
    Handler向子线程发送数据
    Android Touch事件分发
    int 转十六进制
    JVM client模式和Server模式
  • 原文地址:https://www.cnblogs.com/lvyouyw/p/6857629.html
Copyright © 2011-2022 走看看