2017.6.26 旅行 思考记录

来源:互联网 发布:英文缩写查询软件 编辑:程序博客网 时间:2024/06/05 00:32

        这个题其实不算难,但复杂度一定要算清楚、、

        如果没有宗教相同的限制,就是裸的树链剖分

        但有了宗教相同的限制,我们可以想到对每个宗教开线段树、

        直接建是肯定会炸的,所以需要动态开点、、

        这样最复杂情况是   1*n+2*n/2+4*n/4+8*n/8...  所以就是n*logn的空间、、(惊人的小)

        由于这个题它不是让你创算法,所以有个很好的修改方式——单点修改、

        这样删除+增加就是2log的了,而且不用pushdown、

      

          还有一个思路是每个节点开一个splay、、然后动态删除添加。。  它看似能做,是log^2n的,但这样修改时复杂度是不科学的、

         

       一遍ac(主要是套路太死了

     码(变量名混乱)

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;#include<vector>#define N 100005vector<int>v[N];int d[N],fu[N],sz[N],top[N],tot,hson[N],dui[N],pj[N],lpj[N],zj[N],lzj[N],he[N*40],n,m,cnt=N+1,max1[N*40],ll[N*40],rr[N*40],a,b,c,x,y,op,heans,maxans;char ch[55];void dfs1(int now,int fa,int shen){d[now]=shen;fu[now]=fa;sz[now]=1;for(int i=0;i<v[now].size();i++){int nd=v[now][i];if(nd==fa)continue;dfs1(nd,now,shen+1);sz[now]+=sz[nd];if(sz[nd]>sz[hson[now]])hson[now]=nd;}}void dfs2(int now,int tap){top[now]=tap;dui[now]=++tot;pj[tot]=lpj[now];zj[tot]=lzj[now];if(hson[now])dfs2(hson[now],tap);for(int i=0;i<v[now].size();i++){int nd=v[now][i];if(nd==fu[now]||nd==hson[now])continue;dfs2(nd,nd);}}void up(int o){he[o]=he[ll[o]]+he[rr[o]];max1[o]=max(max1[ll[o]],max1[rr[o]]);}void gai(int o,int l,int r){   if(a<=l&&b>=r){if(op==1){c=he[o];he[o]=0;max1[o]=0;}if(op==2){he[o]=c;max1[o]=c;}if(op==3)heans+=he[o];if(op==4)maxans=max(maxans,max1[o]);return;}  // down(o,l,r);      int mid=(l+r)>>1;  if(a<=mid)  {  if(ll[o]==0)ll[o]=++cnt;  gai(ll[o],l,mid);  }  if(b>mid)  {  if(rr[o]==0)rr[o]=++cnt;  gai(rr[o],mid+1,r);    } up(o);}void workgai(int x,int y){    a=dui[x];b=dui[x];if(op==1)//改信用 {gai(zj[a],1,tot);     op=2;    gai(y,1,tot);     zj[a]=y;   }else   {   c=y;   gai(zj[a],1,tot);   }}void workcha(int x,int y){int xyzj=zj[dui[x]];heans=0;maxans=0;while(top[x]!=top[y]){if(d[top[x]]>d[top[y]])swap(x,y);a=dui[top[y]];b=dui[y];gai(xyzj,1,tot);y=fu[top[y]];    }if(d[x]>d[y])swap(x,y);a=dui[x];b=dui[y];gai(xyzj,1,tot);}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%d",&lpj[i],&lzj[i]);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);v[x].push_back(y);v[y].push_back(x);}dfs1(1,1,1);dfs2(1,1);for(int i=1;i<=n;i++){   //cout<<dui[i]<<endl;;op=2;workgai(i,pj[dui[i]]);}for(int i=1;i<=m;i++){scanf("%s",ch);while(ch[0]!='C'&&ch[0]!='Q')scanf("%s",ch);scanf("%d%d",&x,&y);if(ch[0]=='C'){if(ch[1]=='C')op=1;  else op=2;workgai(x,y);}if(ch[0]=='Q'){if(ch[1]=='S')op=3;else op=4;workcha(x,y);if(op==3)printf("%d\n",heans);elseprintf("%d\n",maxans);}}}



原创粉丝点击