• 51Nod1782 圣诞树


    传送门

    我居然忘写题解啦!(记忆废)

    总的来说这题就是道大数据结构……看我代码长度就知道了,真的是长得要死……

    ……

    这题的操作都是路径修改单点查询,因此可以树上差分,问题就变成了维护子树中的所有标记。

    注意到题目要求按照出现次数排序,可以想到用以出现次数为关键字的平衡树维护。虽然这个东西没法快速合并,但它是资瓷启发式合并的,那么我们对每个点再开一个map记录每种礼物的出现次数就好了,合并的时候同时维护平衡树和map。

    合并操作只会进行$n-1$次(废话),因此复杂度为$O(nlog^2 n)$。但是这个做法常数比较大,卡常卡到死才过的……(看上去大多数人都写的平衡树启发式合并,然后这题就变成了卡常大赛……)

    这份代码是卡过常的,所以比较丑,不愿看就不要勉强了……

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<vector>
      4 #include<queue>
      5 #include<map>
      6 #define int unsigned
      7 #define Anti __attribute__((optimize("-Os")))
      8 #define Leaf __inline__ __attribute__((always_inline))
      9 #define dir(x) ((x)==(x)->p->ch[1])
     10 namespace mine{
     11     #define siz (1<<19)
     12     #define frd fread(hd=buf,1,siz,stdin)
     13     #define getchar() (hd==tl?(frd,*hd++):*hd++)
     14     char buf[siz],*hd=buf+siz,*tl=buf+siz;
     15     template<class T>Anti Leaf void readint(register T &__x){
     16         register int __c;
     17         __x=0;
     18         do __c=getchar();while(__c<48);
     19         for(;__c>47;__c=getchar())__x=(__x<<1)+(__x<<3)+(__c^48);
     20     }
     21     template<class T>Anti Leaf void writeint(T __x){
     22         static int __a[25];
     23         register int __i,__j;
     24         __i=0;
     25         do{
     26             __a[__i++]=__x%10^48;
     27             __x/=10;
     28         }while(__x);
     29         for(__j=__i-1;~__j;__j--)putchar(__a[__j]);
     30     }
     31 }
     32 using namespace mine;
     33 using namespace std;
     34 const int maxn=100005;
     35 struct node{
     36     int key,id,size,sum;
     37     node *ch[2],*p;
     38     Anti Leaf node(register int id=0,register int key=0):key(key),id(id),size(1),sum(id){}
     39     Anti Leaf int cmp(register int i,register int k){
     40         if(k!=key)return k>key;
     41         return i>id;
     42     }
     43     Anti Leaf void refresh(){
     44         size=ch[0]->size+ch[1]->size+1;
     45         sum=ch[0]->sum^ch[1]->sum^id;
     46     }
     47 }*null=new node(),*root[maxn];
     48 struct Q{
     49     int k,id;
     50     Q(register int k,register int id):k(k),id(id){}
     51 };
     52 queue<node*>freenodes;
     53 void dfs1(int);
     54 void dfs2(int);
     55 int LCA(int,int);
     56 node *newnode(int,int);
     57 void delnode(node*);
     58 void merge(int,int);
     59 void insert(int,int);
     60 void erase(node*);
     61 node *kth(int,node*);
     62 void splay(node*,node* =null);
     63 void rot(node*,int);
     64 node *findmax(node*);
     65 vector<int>G[maxn];
     66 map<int,node*>mp[maxn];
     67 map<int,int>tmp[maxn];
     68 vector<Q>que[maxn];
     69 int T;
     70 int f[maxn][18],d[maxn];
     71 int n,m,lgn=0,ans[maxn];
     72 //#include<ctime>
     73 signed main(){
     74     null->size=0;
     75     null->ch[0]=null->ch[1]=null->p=null;
     76     fill(root,root+maxn,null);
     77     readint(n);
     78     for(int i=1,x,y;i<n;i++){
     79         readint(x);
     80         readint(y);
     81         G[x].push_back(y);
     82         G[y].push_back(x);
     83     }
     84     dfs1(1);
     85     for(register int j=1;j<=lgn;j++)for(register int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
     86     readint(m);
     87     while(m--){
     88         int x,y,u,v;
     89         readint(x);
     90         readint(y);
     91         readint(v);
     92         readint(u);
     93         register int z=LCA(x,y);
     94         tmp[x][u]+=v;
     95         tmp[y][u]+=v;
     96         tmp[z][u]-=v;
     97         if(f[z][0])tmp[f[z][0]][u]-=v;
     98     }
     99     for(register int x=1;x<=n;x++){
    100         T=x;
    101         for(map<int,int>::iterator it=tmp[x].begin();it!=tmp[x].end();it++)if(it->second){
    102             insert(it->first,it->second);
    103             mp[x][it->first]=root[x];
    104         }
    105         tmp[x].clear();
    106     }
    107     readint(m);
    108     for(register int i=1;i<=m;i++){
    109         int x,k;
    110         readint(x);
    111         readint(k);
    112         que[x].push_back(Q(k,i));
    113     }
    114     dfs2(1);
    115     for(register int i=1;i<=m;i++){
    116         writeint(ans[i]);
    117         putchar('
    ');
    118     }
    119     //fprintf(fopen("con","w"),"%lf",(double)clock()/CLOCKS_PER_SEC);
    120     return 0;
    121 }
    122 Anti void dfs1(int x){
    123     d[x]=d[f[x][0]]+1;
    124     while((1<<lgn)<d[x])lgn++;
    125     for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=f[x][0]){
    126         f[G[x][i]][0]=x;
    127         dfs1(G[x][i]);
    128     }
    129 }
    130 Anti void dfs2(int x){
    131     for(int i=0;i<(int)G[x].size();i++)if(G[x][i]!=f[x][0]){
    132         dfs2(G[x][i]);
    133         merge(x,G[x][i]);
    134     }
    135     T=x;
    136     for(int i=0;i<(int)que[x].size();i++){
    137         if(que[x][i].k>=root[x]->size)ans[que[x][i].id]=root[x]->sum;
    138         else{
    139             splay(kth(que[x][i].k+1,root[x]));
    140             ans[que[x][i].id]=root[x]->ch[0]->sum;
    141         }
    142     }
    143 }
    144 Anti Leaf int LCA(register int x,register int y){
    145     if(d[x]!=d[y]){
    146         if(d[x]<d[y]){x^=y;y^=x;x^=y;}
    147         for(int i=lgn;~i;i--)if(d[f[x][i]]>=d[y])x=f[x][i];
    148     }
    149     if(x==y)return x;
    150     for(register int i=lgn;~i;i--)if(f[x][i]!=f[y][i]){
    151         x=f[x][i];
    152         y=f[y][i];
    153     }
    154     return f[x][0];
    155 }
    156 Anti Leaf node *newnode(register int id,register int key){
    157     register node *x;
    158     if(freenodes.empty())x=new node(id,key);
    159     else{
    160         x=freenodes.front();
    161         freenodes.pop();
    162         *x=node(id,key);
    163     }
    164     x->ch[0]=x->ch[1]=x->p=null;
    165     return x;
    166 }
    167 Anti Leaf void delnode(register node *x){
    168     if(freenodes.size()<maxn<<2)freenodes.push(x);
    169     else delete x;
    170 }
    171 Anti Leaf void merge(register int x,register int y){
    172     if(root[x]==null){
    173         root[x]=root[y];
    174         swap(mp[x],mp[y]);
    175         return;
    176     }
    177     else if(root[y]==null)return;
    178     if(root[x]->size>root[y]->size){
    179         register node *u=findmax(root[y]);
    180         T=y;splay(u);
    181         while(u!=null){
    182             if(mp[x].count(u->id)){
    183                 register node v=*mp[x][u->id];
    184                 T=x;erase(mp[x][u->id]);
    185                 if(u->key+v.key){
    186                     insert(v.id,u->key+v.key);
    187                     mp[x][u->id]=root[x];
    188                 }
    189                 else mp[x].erase(u->id);
    190             }
    191             else{
    192                 T=x;insert(u->id,u->key);
    193                 mp[x][u->id]=root[x];
    194             }
    195             if(u->ch[0]==null)break;
    196             T=y;
    197             splay(findmax(u->ch[0]));
    198             root[y]->ch[1]=null;
    199             delnode(u);
    200             u=root[y];
    201         }
    202         mp[y].clear();
    203         root[y]=null;
    204     }
    205     else{
    206         register node *u=findmax(root[x]);
    207         T=x;splay(u);
    208         while(u!=null){
    209             if(mp[y].count(u->id)){
    210                 register node v=*mp[y][u->id];
    211                 T=y;erase(mp[y][u->id]);
    212                 if(u->key+v.key){
    213                     insert(v.id,u->key+v.key);
    214                     mp[y][u->id]=root[y];
    215                 }
    216                 else mp[y].erase(u->id);
    217             }
    218             else{
    219                 T=y;insert(u->id,u->key);
    220                 mp[y][u->id]=root[y];
    221             }
    222             if(u->ch[0]==null)break;
    223             T=x;
    224             splay(findmax(u->ch[0]));
    225             root[x]->ch[1]=null;
    226             delnode(u);
    227             u=root[x];
    228         }
    229         mp[x].clear();
    230         root[x]=null;
    231         swap(root[x],root[y]);
    232         swap(mp[x],mp[y]);
    233     }
    234 }
    235 Anti Leaf void insert(register int id,register int key){
    236     if(root[T]==null){
    237         root[T]=newnode(id,key);
    238         return;
    239     }
    240     node *rt=root[T];
    241     register int d=0;
    242     while(rt!=null){
    243         d=rt->cmp(id,key);
    244         if(rt->ch[d]!=null)rt=rt->ch[d]; 
    245         else{
    246             rt->ch[d]=newnode(id,key);
    247             rt->ch[d]->p=rt;
    248             break;
    249         }
    250     }
    251     for(node *y=rt;y!=null;y=y->p)y->refresh();
    252     splay(rt->ch[d]);
    253 }
    254 Anti Leaf void erase(register node *x){
    255     splay(x);
    256     if(x->ch[0]!=null){
    257         splay(findmax(x->ch[0]),x);
    258         x->ch[0]->ch[1]=x->ch[1];
    259         if(x->ch[1]!=null)x->ch[1]->p=x->ch[0];
    260         x->ch[0]->p=null;
    261         root[T]=x->ch[0];
    262     }
    263     else if((root[T]=x->ch[1])!=null)x->ch[1]->p=null;
    264     delnode(x);
    265     if(root[T]!=null)root[T]->refresh();
    266 }
    267 Anti Leaf node *kth(register int k,register node *rt){
    268     register int d;
    269     while(rt!=null){
    270         if(k==rt->ch[0]->size+1){
    271             splay(rt);
    272             return rt;
    273         }
    274         if((d=k>rt->ch[0]->size))k-=rt->ch[0]->size+1;
    275         rt=rt->ch[d];
    276     }
    277     return null;
    278 }
    279 Anti Leaf node *findmax(register node *x){
    280     while(x->ch[1]!=null)x=x->ch[1];
    281     return x;
    282 }
    283 Anti Leaf void splay(register node *x,register node *t){
    284     while(x->p!=t){
    285         if(x->p->p==t){
    286             rot(x->p,dir(x)^1);
    287             break;
    288         }
    289         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    290         else rot(x->p,dir(x)^1);
    291         rot(x->p,dir(x)^1);
    292     }
    293 }
    294 Anti Leaf void rot(register node *x,register int d){
    295     register node *y=x->ch[d^1];
    296     if((x->ch[d^1]=y->ch[d])!=null)y->ch[d]->p=x;
    297     if((y->p=x->p)!=null)x->p->ch[dir(x)]=y;
    298     else root[T]=y;
    299     (y->ch[d]=x)->p=y;
    300     x->refresh();
    301     y->refresh();
    302 }
    View Code

    顺便说一下,用平衡树维护出现次数的想法是从我的一道原创题来的:给定一个序列,每次询问区间中出现次数第k多的数。

    特此声明,版权所有……

  • 相关阅读:
    OBS推流工具
    Spring学习笔记(二)
    设计模式
    力扣刷题 二分法 leetcode 刷题 27,26,283,844,977
    论文笔记 Processing Private Queries over Untrusted Data Cloud through Privacy Homomorphism 通过隐私同态处理不可信数据云上的私有查询
    今日链表操作leetcode 24 交换链表中的相邻两个结点
    leetcode刷题 leetcode22中等题 有效括号生成
    npm镜像 yarn镜像 homebrew镜像 各种镜像
    mac m1 pro 搭建php环境
    华为弹性ecs(centOS7)环境构建笔记
  • 原文地址:https://www.cnblogs.com/hzoier/p/6556794.html
Copyright © 2020-2023  润新知