Query on a tree IV SPOJ

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 }
View Code

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 }
View Code
原文地址:https://www.cnblogs.com/hehe54321/p/9285659.html