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 }
upd20181231:
用网上的链分治做法重写了,果然常数小很多,可以A了,然而代码量似乎更大
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<queue> 6 using namespace std; 7 #define fi first 8 #define se second 9 #define mp make_pair 10 #define pb push_back 11 typedef long long ll; 12 typedef unsigned long long ull; 13 typedef pair<int,int> pii; 14 struct E 15 { 16 int to,nxt,d; 17 }e[200011]; 18 int f1[100011],ne; 19 const int inf1=0x3f3f3f3f; 20 struct Set 21 { 22 priority_queue<int> s,t;int sz; 23 void push(int x){s.push(x);++sz;} 24 void erase(int x){t.push(x);--sz;} 25 int top() 26 { 27 while(s.size()&&t.size()&&s.top()==t.top()) 28 s.pop(),t.pop(); 29 return sz?s.top():-inf1; 30 } 31 int sum2()//最大2个之和 32 { 33 if(sz<2) return 0; 34 int a1=top();erase(a1); 35 int a2=top();push(a1); 36 return a1+a2; 37 } 38 }q[100011],&q0=q[0]; 39 int d[100011]; 40 struct I 41 { 42 int da,db,d; 43 //a表示向下最长轻链,d表示到1距离;max{a+d},max{a-d},max{ar+al+dr-dl} 44 }; 45 void merge(I &c,const I &a,const I &b) 46 { 47 c.da=max(a.da,b.da); 48 c.db=max(a.db,b.db); 49 c.d=max(max(a.d,b.d),b.da+a.db); 50 } 51 namespace S 52 { 53 struct D 54 { 55 int lc,rc;I d; 56 }g[1000011]; 57 int mem; 58 #define LC g[u].lc 59 #define RC g[u].rc 60 void upd(int u){merge(g[u].d,g[LC].d,g[RC].d);} 61 I x;int L; 62 /* 63 void init() 64 { 65 g[0].d.da=g[0].d.db=g[0].d.d=-inf1; 66 } 67 inline int gnode() 68 { 69 int t=++mem; 70 g[t].d.da=g[t].d.db=g[t].d.d=g[t].d.a=-inf1; 71 return t; 72 } 73 */ 74 void _setx(int l,int r,int &u) 75 { 76 if(!u) u=++mem; 77 if(l==r) 78 { 79 g[u].d=x; 80 return; 81 } 82 int mid=(l+r)>>1; 83 if(L<=mid) _setx(l,mid,LC); 84 else _setx(mid+1,r,RC); 85 upd(u); 86 } 87 I getx(int L,int R,int l,int r,int u) 88 { 89 if(L<=l&&r<=R) return g[u].d; 90 int mid=(l+r)>>1; 91 if(L<=mid&&mid<R) 92 { 93 I t;merge(t,getx(L,R,l,mid,LC),getx(L,R,mid+1,r,RC)); 94 return t; 95 } 96 else if(L<=mid) 97 return getx(L,R,l,mid,LC); 98 else if(mid<R) 99 return getx(L,R,mid+1,r,RC); 100 } 101 } 102 int dep[100011],sz[100011]; 103 int d2[100011],hson[100011]; 104 int ff[100011]; 105 void dfs1(int u,int fa) 106 { 107 sz[u]=1; 108 int v; 109 for(int k=f1[u];k;k=e[k].nxt) 110 if(e[k].to!=fa) 111 { 112 v=e[k].to; 113 ff[v]=u; 114 dep[v]=dep[u]+1; 115 d[v]=d[u]+e[k].d; 116 dfs1(v,u); 117 sz[u]+=sz[v]; 118 if(sz[v]>sz[hson[u]]) hson[u]=v; 119 } 120 } 121 int b[100011],pl[100011],tp[100011],dwn[100011],len[100011]; 122 int rt[100011],oknum; 123 bool ok[100011]; 124 int n,m; 125 void dfs2(int u,int fa) 126 { 127 ok[u]=1;q[u].push(0); 128 b[++b[0]]=u;pl[u]=b[0]; 129 tp[u]=(u==hson[fa])?tp[fa]:u; 130 if(hson[u]) dfs2(hson[u],u); 131 dwn[u]=hson[u]?dwn[hson[u]]:u; 132 len[u]=dep[dwn[u]]-dep[tp[u]]+1; 133 int v,k; 134 for(k=f1[u];k;k=e[k].nxt) 135 if(e[k].to!=fa&&e[k].to!=hson[u]) 136 { 137 v=e[k].to; 138 dfs2(v,u); 139 q[u].push(d2[v]-d[u]); 140 } 141 { 142 int t=q[u].top(); 143 using namespace S; 144 x.da=t+d[u];x.db=t-d[u];x.d=q[u].sum2(); 145 L=dep[u]-dep[tp[u]]+1;_setx(1,len[u],rt[tp[u]]); 146 } 147 if(u==tp[u]) 148 { 149 const I &t=S::g[rt[u]].d; 150 d2[u]=t.da; 151 q0.push(t.d); 152 } 153 } 154 int main() 155 { 156 int i,x,y,z,t,u,v; 157 char tmp[233]; 158 //S::init(); 159 scanf("%d",&n); 160 for(i=1;i<n;++i) 161 { 162 scanf("%d%d%d",&x,&y,&z); 163 e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;e[ne].d=z; 164 e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;e[ne].d=z; 165 } 166 dfs1(1,0); 167 oknum=n; 168 dfs2(1,0); 169 //printf("%d ",q0.top()); 170 scanf("%d",&m); 171 while(m--) 172 { 173 scanf("%s",tmp); 174 if(tmp[0]=='C') 175 { 176 scanf("%d",&u); 177 if(ok[u]) 178 { 179 --oknum; 180 q[u].erase(0); 181 } 182 else 183 { 184 ++oknum; 185 q[u].push(0); 186 } 187 ok[u]^=1; 188 while(u) 189 { 190 q0.erase(S::g[rt[tp[u]]].d.d); 191 { 192 t=q[u].top(); 193 using namespace S;I &x=S::x; 194 x.da=t+d[u];x.db=t-d[u];x.d=q[u].sum2(); 195 L=dep[u]-dep[tp[u]]+1;_setx(1,len[u],rt[tp[u]]); 196 } 197 u=tp[u];v=ff[u]; 198 const I &t=S::g[rt[u]].d; 199 if(v) q[v].erase(d2[u]-d[v]); 200 d2[u]=t.da; 201 if(v) q[v].push(d2[u]-d[v]); 202 q0.push(t.d); 203 u=v; 204 } 205 } 206 else 207 { 208 if(!oknum) 209 { 210 puts("They have disappeared."); 211 continue; 212 } 213 printf("%d ",q0.top()); 214 } 215 } 216 return 0; 217 }