Query on a tree IV SPOJ - QTREE4
Posted hehe54321
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Query on a tree IV SPOJ - QTREE4相关的知识,希望对你有一定的参考价值。
https://vjudge.net/problem/SPOJ-QTREE4
点分就没有一道不卡常的?
卡常记录:
1.把multiset换成手写的带删除堆(套用pq)(作用很大)
2.把带删除堆里面pq换成用vector+push_heap/pop_heap(作用较小)
1 #pragma GCC optimize("Ofast") 2 #pragma GCC optimize("inline","fast-math","unroll-loops","no-stack-protector") 3 #pragma GCC diagnostic error "-fwhole-program" 4 #pragma GCC diagnostic error "-fcse-skip-blocks" 5 #pragma GCC diagnostic error "-funsafe-loop-optimizations" 6 #pragma GCC diagnostic error "-std=c++14" 7 #include<cstdio> 8 #include<algorithm> 9 #include<queue> 10 using namespace std; 11 struct E 12 { 13 int to,nxt,d; 14 }e[200100]; 15 int f1[100100],ne; 16 int ff[100100],n,sum,fx[100100],sz[100100]; 17 int eu[200100],pos[200100],dpx[200100],dpx2[200100],st[200100][20],log2x[200100],lft[30]; 18 int root; 19 bool fl[100100],vis[100100]; 20 struct xxx 21 { 22 priority_queue<int> q1,q2;int sz; 23 void insert(int x){q1.push(x);++sz;} 24 void erase(int x){q2.push(x);--sz;} 25 int size() {return sz;} 26 void cl() 27 { 28 while(!q1.empty()&&!q2.empty()&&q1.top()==q2.top()) q1.pop(),q2.pop(); 29 } 30 void pop() 31 { 32 cl();q1.pop();--sz; 33 } 34 int top() 35 { 36 cl();return q1.top(); 37 } 38 bool empty() {return sz==0;} 39 }; 40 xxx s[100100],s2[100100],s3; 41 //s[i]:i点管辖的连通块各个点到i点上层重心的距离 42 //s2[i]:i点的各个下层重心的s的最大值,**再加上一个0(i点到自身距离) 43 //s3:各个s2的前2大值之和 44 int getdis(int x,int y) 45 { 46 int l=pos[x],r=pos[y];if(l>r) swap(l,r); 47 int k=log2x[r-l+1],t=dpx[pos[st[l][k]]]>dpx[pos[st[r-lft[k]+1][k]]]?st[r-lft[k]+1][k]:st[l][k]; 48 return dpx2[pos[x]]+dpx2[pos[y]]-2*dpx2[pos[t]]; 49 } 50 void getroot(int u,int fa) 51 { 52 sz[u]=1;fx[u]=0; 53 for(int k=f1[u];k;k=e[k].nxt) 54 if(!vis[e[k].to]&&e[k].to!=fa) 55 { 56 getroot(e[k].to,u); 57 sz[u]+=sz[e[k].to]; 58 fx[u]=max(fx[u],sz[e[k].to]); 59 } 60 fx[u]=max(fx[u],sum-sz[u]); 61 if(fx[u]<fx[root]) root=u; 62 } 63 void getsz(int u,int fa) 64 { 65 sz[u]=1; 66 for(int k=f1[u];k;k=e[k].nxt) 67 if(!vis[e[k].to]&&e[k].to!=fa) 68 { 69 getsz(e[k].to,u); 70 sz[u]+=sz[e[k].to]; 71 } 72 } 73 void getdeep(int u,int fa) 74 { 75 s[root].insert(getdis(u,ff[root])); 76 for(int k=f1[u];k;k=e[k].nxt) 77 if(!vis[e[k].to]&&e[k].to!=fa) 78 getdeep(e[k].to,u); 79 } 80 char tmp[20]; 81 int getmax2(int p) 82 { 83 if(s2[p].size()<2) return -0x3f3f3f3f; 84 int t1=s2[p].top();s2[p].pop();int t2=s2[p].top();s2[p].insert(t1); 85 return t1+t2; 86 } 87 void solve(int u) 88 { 89 vis[u]=1; 90 s2[u].insert(0); 91 for(int k=f1[u];k;k=e[k].nxt) 92 if(!vis[e[k].to]) 93 { 94 getsz(e[k].to,0);sum=sz[e[k].to]; 95 root=0;getroot(e[k].to,0); 96 ff[root]=u;getdeep(root,0); 97 if(!s[root].empty()) s2[u].insert(s[root].top()); 98 solve(root); 99 } 100 s3.insert(getmax2(u)); 101 } 102 void dfs1(int u,int fa,int d,int d2) 103 { 104 eu[++eu[0]]=u;pos[u]=eu[0];dpx[eu[0]]=d;dpx2[eu[0]]=d2; 105 for(int k=f1[u];k;k=e[k].nxt) 106 if(e[k].to!=fa) 107 { 108 dfs1(e[k].to,u,d+1,d2+e[k].d); 109 eu[++eu[0]]=u; 110 dpx[eu[0]]=d; 111 dpx2[eu[0]]=d2; 112 } 113 } 114 //void debugxxxx(multiset<int>& s) 115 //{ 116 // for(auto i : s) printf("%d ",i); 117 // puts("test"); 118 //} 119 void change(int u) 120 { 121 int now; 122 s3.erase(getmax2(u)); 123 if(!fl[u]) s2[u].erase(0); 124 for(now=u;ff[now];now=ff[now]) 125 { 126 s3.erase(getmax2(ff[now])); 127 if(!s[now].empty()) s2[ff[now]].erase(s[now].top()); 128 if(!fl[u]) s[now].erase(getdis(u,ff[now])); 129 } 130 fl[u]^=1; 131 if(!fl[u]) s2[u].insert(0); 132 s3.insert(getmax2(u)); 133 for(now=u;ff[now];now=ff[now]) 134 { 135 if(!fl[u]) s[now].insert(getdis(u,ff[now])); 136 if(!s[now].empty()) s2[ff[now]].insert(s[now].top()); 137 s3.insert(getmax2(ff[now])); 138 } 139 } 140 int num; 141 int main() 142 { 143 lft[0]=1; 144 fx[0]=0x3f3f3f3f; 145 int i,j,a,b,la=0,q,t,c; 146 for(i=1;i<=27;i++) lft[i]=(lft[i-1]<<1); 147 for(i=1;i<=200000;i++) 148 { 149 if(i>=lft[la+1]) ++la; 150 log2x[i]=la; 151 } 152 scanf("%d",&n); 153 for(i=1;i<n;i++) 154 { 155 scanf("%d%d%d",&a,&b,&c); 156 e[++ne].to=b;e[ne].nxt=f1[a];e[ne].d=c;f1[a]=ne; 157 e[++ne].to=a;e[ne].nxt=f1[b];e[ne].d=c;f1[b]=ne; 158 } 159 dfs1(1,0,0,0); 160 for(i=1;i<=eu[0];i++) st[i][0]=eu[i]; 161 for(j=1;(1<<j)<=eu[0];j++) 162 for(i=1;i+lft[j]-1<=eu[0];i++) 163 if(dpx[pos[st[i][j-1]]]>dpx[pos[st[i+lft[j-1]][j-1]]]) 164 st[i][j]=st[i+lft[j-1]][j-1]; 165 else 166 st[i][j]=st[i][j-1]; 167 sum=n;getroot(1,0); 168 solve(root); 169 scanf("%d",&q); 170 num=n; 171 while(q--) 172 { 173 scanf("%s",tmp); 174 if(tmp[0]==‘A‘) 175 { 176 if(num==0) printf("They have disappeared. "); 177 else if(num==1) printf("0 "); 178 else printf("%d ",max(s3.top(),0)); 179 } 180 else if(tmp[0]==‘C‘) 181 { 182 scanf("%d",&t); 183 if(fl[t]) num++;else num--; 184 change(t); 185 } 186 } 187 return 0; 188 }
以上是关于Query on a tree IV SPOJ - QTREE4的主要内容,如果未能解决你的问题,请参考以下文章
spoj375 QTREE - Query on a tree