• bzoj3262: 陌上花开(树套树)


      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <algorithm>
      6 #define maxn 100005
      7 #define maxm 200005
      8 #define maxk 2000005
      9 using namespace std;
     10 
     11 int n,K,temp,tot,root[maxm*4],ans[maxn],Ans[maxn],sum[maxn],fa[maxk],size[maxk],times[maxk],son[maxk][2],val[maxk];
     12 struct seg{
     13     int x,y,z;
     14 }a[maxn],b[maxn];
     15 bool comp(seg x,seg y){
     16     if (x.x!=y.x) return x.x<y.x;
     17     if (x.y!=y.y) return x.y<y.y;
     18     return x.z<y.z;
     19 }
     20 struct Tsegment{
     21     void prepare(){tot=0,memset(times,0,sizeof(times)),memset(son,0,sizeof(son));}
     22     void query(int k,int x,int op){
     23         int y=root[k]; if (y==0) return; bool bo;
     24         for (;;){
     25             if (y==0) break;
     26             bo=0;
     27             if (val[y]==x) ans[op]+=(size[son[y][0]]+times[y]),bo=1;
     28             else if (x>val[y]) ans[op]+=(size[son[y][0]]+times[y]),y=son[y][1];
     29             else y=son[y][0];
     30             if (bo==1) break;
     31         }
     32     }
     33     int which(int x){
     34         return son[fa[x]][1]==x;
     35     }
     36     void update(int x){
     37         size[x]=size[son[x][0]]+size[son[x][1]]+times[x];
     38     }
     39     void rotata(int x){
     40         int y=fa[x],d=which(x),dd=which(y);
     41         if (fa[y]) son[fa[y]][dd]=x; fa[x]=fa[y];
     42         fa[son[x][d^1]]=y,son[y][d]=son[x][d^1];
     43         fa[y]=x,son[x][d^1]=y,update(y);
     44     }
     45     void splay(int x,int goal,int op){
     46         while (fa[x]!=goal){
     47             if (fa[fa[x]]==goal) rotata(x);
     48             else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
     49             else rotata(x),rotata(x);
     50         }
     51         update(x); if (goal==0) root[op]=x;
     52     }
     53     void insert(int k,int x,int z){
     54         int y=root[k]; bool bo;
     55         if (y==0){
     56             root[k]=++tot,val[tot]=x,size[tot]=times[tot]=z,fa[tot]=son[tot][0]=son[tot][1]=0;
     57             return;
     58         }
     59         for (;;){
     60             bo=0;
     61             if (val[y]==x) times[y]+=z,size[y]+=z,bo=1,splay(y,0,k);
     62             else if (x<val[y]){
     63                 if (!son[y][0]) val[++tot]=x,son[y][0]=tot,fa[tot]=y,size[tot]=times[tot]=z,bo=1,splay(tot,0,k);
     64                 else y=son[y][0];
     65             }else{
     66                 if (!son[y][1]) val[++tot]=x,son[y][1]=tot,fa[tot]=y,size[tot]=times[tot]=z,bo=1,splay(tot,0,k);
     67                 else y=son[y][1];
     68             }
     69             if (bo==1) break;
     70         }
     71     }
     72 }Splay;
     73 struct Fsegment{
     74     void prepare(){memset(root,0,sizeof(root));}
     75     void query(int k,int l,int r,int x,int y,int z,int op){
     76         if (l>=x&&r<=y){
     77             Splay.query(k,z,op);
     78             return;
     79         }int mid=(l+r)/2;
     80         if (x<=mid) query(k*2,l,mid,x,y,z,op);
     81         if (y>mid) query(k*2+1,mid+1,r,x,y,z,op);
     82     }
     83     void insert(int k,int l,int r,int x,int y,int z){
     84         Splay.insert(k,y,z);
     85         if (l==r) return; int mid=(l+r)/2;
     86         if (x<=mid) insert(k*2,l,mid,x,y,z);
     87         else insert(k*2+1,mid+1,r,x,y,z);
     88     }
     89 }Tree;
     90 struct Ksegment{
     91     void work(){
     92         memset(ans,0,sizeof(ans));
     93         for (int i=1;i<=temp;i++){
     94             Tree.query(1,1,K,1,b[i].y,b[i].z,i);
     95             Tree.insert(1,1,K,b[i].y,b[i].z,sum[i]);
     96         }
     97         memset(Ans,0,sizeof(Ans));
     98         for (int i=1;i<=temp;i++) Ans[ans[i]+sum[i]-1]+=sum[i];
     99         for (int i=0;i<n;i++) printf("%d
    ",Ans[i]);
    100     }
    101 }Task;
    102 int main(){
    103     memset(fa,0,sizeof(fa));
    104     memset(son,0,sizeof(son));
    105     memset(val,0,sizeof(val));
    106     a[0].x=a[0].y=a[0].z=0;
    107     scanf("%d%d",&n,&K);
    108     for (int i=1;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    109     sort(a+1,a+n+1,comp);
    110     memset(sum,0,sizeof(sum));
    111     temp=tot=0;
    112     for (int i=1;i<=n;i++){
    113         if (a[i].x==a[i-1].x&&a[i].y==a[i-1].y&&a[i].z==a[i-1].z) sum[temp]++;
    114         else sum[++temp]=1,b[temp].x=a[i].x,b[temp].y=a[i].y,b[temp].z=a[i].z;
    115     }
    116     Tree.prepare();
    117     Task.work();
    118     return 0;
    119 }
    View Code

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3262

    题目大意:见题目。

    做法:上次我用的是cdq分治+树状数组,这次写的是线段树套splay,比较裸的树套树了,,,一维排序,另外两维在树套树上维护一下即可。

    树套树。

  • 相关阅读:
    php开启伪静态(2转)
    php,apache伪静态(1转)
    sql 字段先计算后再拿比对的字段进行比对 效率提升100倍
    使用 PHP 读取文本(TXT)文件 并分页显示
    php给一张图片加上水印效果
    PHP命名空间(Namespace)的使用详解(转)
    php随机获取金山词霸每日一句
    网络报文分析利器eBPF
    这个世界变得有多复杂
    个人收藏网站推荐(一)
  • 原文地址:https://www.cnblogs.com/OYzx/p/5540197.html
Copyright © 2020-2023  润新知