• 无题


    没错,这就是上次联考的D1T3逃离……

    从昨天下午就开始写了,写了快一天,到现在终于过了……

    我做这题最大的感想就是:我衷心祝愿出题人全家身体健康……(咳闹着玩的,其实我也出过毒瘤题……

    看看代码长度,你们大概就能理解我的心情了……

    不多说了放代码,注释我懒得删了,不要介意……

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cassert>
      5 #include<ext/pb_ds/assoc_container.hpp>
      6 #include<ext/pb_ds/tree_policy.hpp>
      7 #include<ext/pb_ds/priority_queue.hpp>
      8 #define isroot(x) ((x)->p==null||((x)!=(x)->p->ch[0]&&(x)!=(x)->p->ch[1]))
      9 #define dir(x) ((x)==(x)->p->ch[1])
     10 using namespace std;
     11 using namespace __gnu_pbds;
     12 const int maxn=100010;
     13 const long long INF=1000000000000000000ll;
     14 struct binary_heap{
     15     __gnu_pbds::priority_queue<long long,less<long long>,binary_heap_tag>q1,q2;
     16     binary_heap(){}
     17     void push(long long x){if(x>(-INF)>>2)q1.push(x);}
     18     void erase(long long x){if(x>(-INF)>>2)q2.push(x);}
     19     long long top(){
     20         if(empty())return -INF;
     21         while(!q2.empty()&&q1.top()==q2.top()){
     22             q1.pop();
     23             q2.pop();
     24         }
     25         return q1.top();
     26     }
     27     long long top2(/* bool flag=false */){
     28         if(size()<2)return -INF;
     29         long long a=top();
     30         erase(a);
     31         long long b=top();//if(flag)printf("(a=%I64d b=%I64d)
    ",a,b);
     32         push(a);
     33         return a+b;
     34     }
     35     int size(){return q1.size()-q2.size();}
     36     bool empty(){return q1.size()==q2.size();}
     37 }heap;//全局堆维护每条链的最大子段和
     38 struct node{
     39     long long sum,maxsum,prefix,suffix;
     40     int key;
     41     binary_heap heap;//每个点的堆存的是它的子树中到它的最远距离,如果它是黑点的话还会包括自己
     42     node *ch[2],*p;
     43     bool rev;
     44     node(int k=0):sum(k),maxsum(-INF),prefix(-INF),suffix(-INF),key(k),rev(false){}
     45     inline void pushdown(){
     46         if(!rev)return;
     47         ch[0]->rev^=true;
     48         ch[1]->rev^=true;
     49         swap(ch[0],ch[1]);
     50         swap(prefix,suffix);
     51         rev=false;
     52     }
     53     inline void refresh(){//assert(!rev);
     54         pushdown();
     55         ch[0]->pushdown();
     56         ch[1]->pushdown();
     57         sum=ch[0]->sum+ch[1]->sum+key;
     58         prefix=max(ch[0]->prefix,ch[0]->sum+key+ch[1]->prefix);
     59         suffix=max(ch[1]->suffix,ch[1]->sum+key+ch[0]->suffix);
     60         maxsum=max(max(ch[0]->maxsum,ch[1]->maxsum),ch[0]->suffix+key+ch[1]->prefix);
     61         if(!heap.empty()){
     62             prefix=max(prefix,ch[0]->sum+key+heap.top());
     63             suffix=max(suffix,ch[1]->sum+key+heap.top());
     64             maxsum=max(maxsum,max(ch[0]->suffix,ch[1]->prefix)+key+heap.top());
     65             if(heap.size()>1){
     66                 /* int a=heap.top();
     67                 heap.erase(a); */
     68                 maxsum=max(maxsum,heap.top2()+key);
     69                 /* heap.push(a); */
     70             }
     71         }
     72         /* pushdown();
     73         ch[0]->pushdown();
     74         ch[1]->pushdown();
     75         long long lm=ch[0]->maxsum,rm=ch[1]->maxsum;
     76         long long llm=ch[0]->prefix,rrm=ch[1]->suffix,lrm=ch[0]->suffix,rlm=ch[1]->prefix;
     77         long long lsum=ch[0]->sum,rsum=ch[1]->sum;
     78         long long k=heap.top()+key;
     79          
     80         maxsum=max(max(max(lm,rm),rlm+lrm+key),max(lrm,rlm)+k);
     81         maxsum=max(maxsum,heap.top2()+key);
     82         //if (p->mx<0) p->mx=-inf;
     83          
     84         prefix=max(llm,lsum+max(key+rlm,k));
     85         //if (p->lmx<0) p->lmx=-inf;
     86         suffix=max(rrm,rsum+max(key+lrm,k));
     87         //if (p->rmx<0) p->rmx=-inf;
     88          
     89         sum=lsum+rsum+key; */
     90     }
     91 }null[maxn<<1],*ptr=null;
     92 void addedge(int,int,int);
     93 void deledge(int,int);
     94 void modify(int,int,int);
     95 void modify_color(int);
     96 node *newnode(int);
     97 node *access(node*);
     98 void makeroot(node*);
     99 void link(node*,node*);
    100 void cut(node*,node*);
    101 void splay(node*);
    102 void rot(node*,int);
    103 queue<node*>freenodes;
    104 tree<pair<int,int>,node*>mp;
    105 bool col[maxn]={false};
    106 char c;
    107 int n,m,k,x,y,z;
    108 int main(){
    109     null->ch[0]=null->ch[1]=null->p=null;
    110     scanf("%d%d%d",&n,&m,&k);
    111     for(int i=1;i<=n;i++){
    112         newnode(0);
    113         //heap.push(-0x3f3f3f3f);
    114     }
    115     heap.push(0);
    116     while(k--){
    117         scanf("%d",&x);
    118         col[x]=true;
    119         null[x].heap.push(0);
    120     }//print_all();
    121     for(int i=1;i<n;i++){
    122         scanf("%d%d%d",&x,&y,&z);
    123         if(x>y)swap(x,y);
    124         addedge(x,y,z);//printf("%d
    ",heap.top());print_all();
    125     }
    126     //printf("---------------------------------OK!!!---------------------------------
    ");
    127     while(m--){
    128         scanf(" %c%d",&c,&x);
    129         if(c=='A'){
    130             scanf("%d",&y);
    131             if(x>y)swap(x,y);
    132             deledge(x,y);
    133         }
    134         else if(c=='B'){
    135             scanf("%d%d",&y,&z);
    136             if(x>y)swap(x,y);
    137             addedge(x,y,z);
    138         }
    139         else if(c=='C'){
    140             scanf("%d%d",&y,&z);
    141             if(x>y)swap(x,y);
    142             modify(x,y,z);
    143         }
    144         else modify_color(x);//printf("size=%d
    ",heap.size());
    145         printf("%lld
    ",(heap.top()>0?heap.top():-1));//print_all();
    146     }
    147     return 0;
    148 }
    149 void addedge(int x,int y,int z){//printf("addedge(%d,%d,%d)
    ",x,y,z);
    150     node *tmp;
    151     if(freenodes.empty())tmp=newnode(z);
    152     else{
    153         tmp=freenodes.front();
    154         freenodes.pop();
    155         *tmp=node(z);
    156     }
    157     tmp->ch[0]=tmp->ch[1]=tmp->p=null;heap.push(tmp->maxsum);//printf("push(%I64d)
    ",tmp->maxsum);
    158     link(tmp,null+x);
    159     link(tmp,null+y);
    160     mp[make_pair(x,y)]=tmp;
    161 }
    162 void deledge(int x,int y){//printf("deledge(%d,%d)
    ",x,y);
    163     node *tmp=mp[make_pair(x,y)];
    164     cut(tmp,null+x);
    165     cut(tmp,null+y);
    166     freenodes.push(tmp);
    167     heap.erase(tmp->maxsum);//printf("erase(%I64d)
    ",tmp->maxsum);
    168     mp.erase(make_pair(x,y));
    169 }
    170 void modify(int x,int y,int z){
    171     node *tmp=mp[make_pair(x,y)];
    172     makeroot(tmp);
    173     tmp->pushdown();
    174     heap.erase(tmp->maxsum);//printf("erase(%I64d)
    ",tmp->maxsum);
    175     tmp->key=z;
    176     tmp->refresh();
    177     heap.push(tmp->maxsum);//printf("push(%I64d)
    ",tmp->maxsum);
    178 }
    179 void modify_color(int x){
    180     makeroot(null+x);
    181     col[x]^=true;
    182     if(col[x])null[x].heap.push(0);
    183     else null[x].heap.erase(0);
    184     heap.erase(null[x].maxsum);//printf("erase(%I64d)
    ",null[x].maxsum);
    185     null[x].refresh();
    186     heap.push(null[x].maxsum);//printf("push(%I64d)
    ",null[x].maxsum);
    187 }
    188 node *newnode(int k){
    189     *(++ptr)=node(k);
    190     ptr->ch[0]=ptr->ch[1]=ptr->p=null;
    191     return ptr;
    192 }
    193 node *access(node *x){
    194     splay(x);//printf("access(%d)
    ",x-null);
    195     heap.erase(x->maxsum);//printf("erase(%I64d)
    ",x->maxsum);
    196     x->refresh();//printf("x->maxsum=%I64d key=%d top()=%I64d x->heap.top()+key+ch[1]->prefix=%I64d
    ",x->maxsum,x->key,x->heap.top(),x->heap.top()+x->key+x->ch[1]->prefix);
    197     if(x->ch[1]!=null){
    198         x->ch[1]->pushdown();
    199         x->heap.push(x->ch[1]->prefix);x->refresh();//printf("x.heap.push(%I64d) top()=%I64d top2()=%I64d size=%d lc->suffix=%I64d
    ",x->ch[1]->prefix,x->heap.top(),x->heap.top2(x==null+108),x->heap.size(),x->ch[0]->suffix);
    200         heap.push(x->ch[1]->maxsum);//printf("push(%I64d)
    ",x->ch[1]->maxsum);
    201     }
    202     x->ch[1]=null;
    203     x->refresh();//printf("x->maxsum=%I64d
    ",x->maxsum);
    204     node *y=x;
    205     x=x->p;//printf("Begin!
    ");
    206     while(x!=null){
    207         splay(x);//printf("x=%d y=%d
    ",x-null,y-null);
    208         heap.erase(x->maxsum);//printf("erase(%I64d)
    ",x->maxsum);
    209         if(x->ch[1]!=null){
    210             x->ch[1]->pushdown();
    211             x->heap.push(x->ch[1]->prefix);
    212             heap.push(x->ch[1]->maxsum);//printf("push(%I64d)
    ",x->ch[1]->maxsum);
    213         }
    214         x->heap.erase(y->prefix);
    215         x->ch[1]=y;
    216         (y=x)->refresh();//printf("maxsum=%I64d
    ",y->maxsum);
    217         x=x->p;
    218     }//printf("Final
    ");
    219     heap.push(y->maxsum);//printf("push(%I64d)
    ",y->maxsum);printf("Finished!
    ");
    220     return y;
    221 }
    222 void makeroot(node *x){
    223     access(x);
    224     splay(x);
    225     x->rev^=true;
    226 }
    227 void link(node *x,node *y){//新添一条虚边,维护y对应的堆
    228     //printf("link(%d,%d)
    ",x-null,y-null);
    229     makeroot(x);
    230     makeroot(y);
    231     x->pushdown();
    232     x->p=y;
    233     heap.erase(y->maxsum);//printf("erase(%I64d)
    ",y->maxsum);
    234     y->heap.push(x->prefix);
    235     y->refresh();
    236     heap.push(y->maxsum);//printf("push(%I64d)
    ",y->maxsum);
    237     //printf("now top()=%I64d
    ",(heap.empty()?-1:heap.top()));
    238 }
    239 void cut(node *x,node *y){//断开一条实边,一条链变成两条链,需要维护全局堆
    240     makeroot(x);//printf("cut(%d,%d)
    ",x-null,y-null);
    241     access(y);
    242     splay(y);
    243     heap.erase(y->maxsum);//printf("erase(%I64d)
    ",y->maxsum);
    244     heap.push(y->ch[0]->maxsum);//printf("push(%I64d)
    ",y->ch[0]->maxsum);
    245     y->ch[0]->p=null;
    246     y->ch[0]=null;
    247     y->refresh();
    248     heap.push(y->maxsum);//printf("push(%I64d)
    ",y->maxsum);
    249     //printf("now top()=%I64d
    ",(heap.empty()?-1:heap.top()));
    250 }
    251 void splay(node *x){
    252     /* static node *s[maxn<<1];
    253     int top=0;
    254     node *u=x;
    255     while(!isroot(u)){
    256         s[++top]=u;
    257         u=u->p;
    258     }
    259     u->pushdown();
    260     while(top)s[top--]->pushdown(); */
    261     x->pushdown();
    262     while(!isroot(x)){
    263         if(!isroot(x->p))x->p->p->pushdown();
    264         x->p->pushdown();
    265         x->pushdown();
    266         if(isroot(x->p)){
    267             rot(x->p,dir(x)^1);
    268             break;
    269         }
    270         if(dir(x)==dir(x->p))rot(x->p->p,dir(x->p)^1);
    271         else rot(x->p,dir(x)^1);
    272         rot(x->p,dir(x)^1);
    273     }
    274 }
    275 void rot(node *x,int d){
    276     node *y=x->ch[d^1];
    277     if((x->ch[d^1]=y->ch[d])!=null)y->ch[d]->p=x;
    278     y->p=x->p;
    279     if(!isroot(x))x->p->ch[dir(x)]=y;
    280     (y->ch[d]=x)->p=y;
    281     x->refresh();
    282     y->refresh();
    283 }
    View Code

    UPD:

    在虚拟机里跑结果TLE了(跑的非常慢,20s都出不来),然后把pb_ds换成std::map和std::priority_queue就过了= =

    真是玄学,用pb_ds在win7跑的飞快(好吧其实跟std::对应数据结构速度基本一样),但是在Linux里感觉复杂度降了一级……

    这个故事告诉我们,没事不要乱玩pb_ds,乖乖用std::……

  • 相关阅读:
    关于IE高级设置里取消“禁用脚本调试”勾选无效的解决方式
    使用NetworkStream收取数据不全问题讨论,列举目前方式,求最佳解决方式
    EntityFramework学习笔记2ORM及EntityFramework简介
    Asp.Net MVC4.0 官方教程 入门指南之一 入门介绍
    EntityFramework学习笔记4实体数据模型及增、删、改操作
    EntityFramework学习笔记3VS2010安装EF5.0
    如果页面引用了外部JS代码,会被IE缓存的解决方法
    EntityFramework学习笔记1写在学习之前
    【专题】概率dp求期望
    金华网赛G(最大费用最大流)&hdu4406
  • 原文地址:https://www.cnblogs.com/hzoier/p/6668177.html
Copyright © 2020-2023  润新知