无题

没错,这就是上次联考的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)\n",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\n",heap.top());print_all();
125     }
126     //printf("---------------------------------OK!!!---------------------------------\n");
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\n",heap.size());
145         printf("%lld\n",(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)\n",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)\n",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)\n",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)\n",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)\n",tmp->maxsum);
175     tmp->key=z;
176     tmp->refresh();
177     heap.push(tmp->maxsum);//printf("push(%I64d)\n",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)\n",null[x].maxsum);
185     null[x].refresh();
186     heap.push(null[x].maxsum);//printf("push(%I64d)\n",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)\n",x-null);
195     heap.erase(x->maxsum);//printf("erase(%I64d)\n",x->maxsum);
196     x->refresh();//printf("x->maxsum=%I64d key=%d top()=%I64d x->heap.top()+key+ch[1]->prefix=%I64d\n",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\n",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)\n",x->ch[1]->maxsum);
201     }
202     x->ch[1]=null;
203     x->refresh();//printf("x->maxsum=%I64d\n",x->maxsum);
204     node *y=x;
205     x=x->p;//printf("Begin!\n");
206     while(x!=null){
207         splay(x);//printf("x=%d y=%d\n",x-null,y-null);
208         heap.erase(x->maxsum);//printf("erase(%I64d)\n",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)\n",x->ch[1]->maxsum);
213         }
214         x->heap.erase(y->prefix);
215         x->ch[1]=y;
216         (y=x)->refresh();//printf("maxsum=%I64d\n",y->maxsum);
217         x=x->p;
218     }//printf("Final\n");
219     heap.push(y->maxsum);//printf("push(%I64d)\n",y->maxsum);printf("Finished!\n");
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)\n",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)\n",y->maxsum);
234     y->heap.push(x->prefix);
235     y->refresh();
236     heap.push(y->maxsum);//printf("push(%I64d)\n",y->maxsum);
237     //printf("now top()=%I64d\n",(heap.empty()?-1:heap.top()));
238 }
239 void cut(node *x,node *y){//断开一条实边,一条链变成两条链,需要维护全局堆
240     makeroot(x);//printf("cut(%d,%d)\n",x-null,y-null);
241     access(y);
242     splay(y);
243     heap.erase(y->maxsum);//printf("erase(%I64d)\n",y->maxsum);
244     heap.push(y->ch[0]->maxsum);//printf("push(%I64d)\n",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)\n",y->maxsum);
249     //printf("now top()=%I64d\n",(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::……

posted @ 2017-04-05 12:39  AntiLeaf  阅读(230)  评论(0编辑  收藏  举报