2017.5.29-6.3 城市规划 思考记录(非常不容易)

来源:互联网 发布:海康威视有线连接网络 编辑:程序博客网 时间:2024/06/06 00:47

          这个题就是让线段树维护区间连通性

          用并查集维护,传左右端点的联通情况就可以了

    

         但是,这题的实际难度在于怎么让它们正确的合并?

       会出现非常多的问题:

           1、子节点能否和父节点共用一个并查集?明显不行,有可能合并父节点时子节点发生改变   方案:对每个节点建立独立并查集

           2、- | -   在不在一个并查集?      答案:不在

           3、OO   在不在一个并查集?      答案:在

           4、合并左右区间的端点能否直接取值?明显不行,如左边左端是 1,1,2    右边左端是1,2,2,   它们就在一起了      方案:右端点都+2*m 

           5、合并时size能否直接相加?        明显不行,两边都有城市时要-1,,所以并查集还要维护父亲的城市的有无

           6、合并与取size的顺序?            先取size 再 合并

           7、将4*m合成2*m能否直接对应?   明显不行,这样的话这个并查集范围就会在1~4*m之间,这样下一级就会炸  方案:把4*m缩成2*m、

           8、节点对应的节点必须非常清楚,已经处理完了的和没处理的离散对应匹配

        

           但是,这题只给64MB,所以4*m的要单独拿出来、、(重新写、、)



码(调试信息就不删了,看看多麻烦吧):

#include<iostream>#include<cstdio>using namespace std;#include<algorithm>#include<cstring>#define N 100000#define zuo o<<1,l,mid#define you o<<1|1,mid+1,rint fu[N<<2][14],ywcs[N<<2][14],q,sz[N<<2],n,m,a,b,ans,i,j,fu2[50],ywcs2[55];char ch,ch2,tu[N][7];bool yi;int find(int now,int o){if(fu[o][now]==now)return now;else  {fu[o][now]=find(fu[o][now],o);}return fu[o][now];}int find2(int now){if(fu2[now]==now)return now;else  {fu2[now]=find2(fu2[now]);}return fu2[now];}void up(int o,int mid){int l=o<<1,r=o<<1|1,i;sz[o]=sz[l]+sz[r];memset(ywcs2,0,sizeof(ywcs2));for(i=1;i<=m;i++){fu2[i]=find(i,l);ywcs2[fu2[i]]=max(ywcs[l][find(i,l)],ywcs2[fu2[i]]);ywcs[o][i]=0;fu2[m+i]=find(i+m,l);ywcs2[fu2[i+m]]=max(ywcs[l][find(i+m,l)],ywcs2[fu2[i+m]]);ywcs[o][i+m]=0;fu2[2*m+i]=find(i,r)+m*2;ywcs2[fu2[2*m+i]]=max(ywcs[r][find(i,r)],ywcs2[fu2[2*m+i]]);//ywcs[o][i+2*m]=0;//ywcs[fu[o*28+i]]=ywcs[fu[find(l*28+i)]];fu2[i+3*m]=find(i+m,r)+m*2;ywcs2[fu2[3*m+i]]=max(ywcs[r][find(i+m,r)],ywcs2[fu2[3*m+i]]);//ywcs[o][i+3*m]=0;//ywcs[fu[o*28+m+i]]=ywcs[fu[find(r*28+i+14)]];}//for(i=1;i<=m;i++)//cout<<find2(i)<<" ";//cout<<endl;//for(i=1;i<=m;i++)//cout<<ywcs2[find2(i)]<<" ";//cout<<endl;//for(i=1+m;i<=2*m;i++)//cout<<find2(i)<<" ";//cout<<endl;//for(i=1+m;i<=2*m;i++)//cout<<ywcs2[find2(i)]<<" ";//cout<<endl;//for(i=1+2*m;i<=3*m;i++)//cout<<find2(i)<<" ";//cout<<endl;//for(i=1+2*m;i<=m*3;i++)//cout<<ywcs2[find2(i)]<<" ";//cout<<endl;//for(i=1+3*m;i<=4*m;i++)//cout<<find2(i)<<" ";//cout<<endl;//for(i=1+3*m;i<=4*m;i++)//cout<<ywcs2[find2(i)]<<" ";//cout<<endl<<endl;for(i=1;i<=m;i++){   if(((tu[mid][i]=='|'||tu[mid][i]=='+')&&tu[mid+1][i]!='.'&&tu[mid+1][i]!='-')||((tu[mid+1][i]=='|'||tu[mid+1][i]=='+')&&tu[mid][i]!='.'&&tu[mid][i]!='-')||(tu[mid][i]=='O'&&tu[mid+1][i]=='O')){int ll=find2(i+m),rr=find2(i+2*m);if(ll==rr)continue;fu2[ll]=rr;     if(ywcs2[rr]==1&&ywcs2[ll]==1)sz[o]--;ywcs2[rr]=max(ywcs2[rr],ywcs2[ll]);   }}int dui[30];//memset(dui,0,sizeof(dui));//cout<<endl<<"papapa ";for(i=1;i<=m;i++){dui[find2(i)]=i;  //cout<<find2(i)<<" "<<i<<"     papapa ";}//cout<<endl<<"papapa ";for(i=3*m+1;i<=4*m;i++){dui[find2(i)]=i-2*m;//cout<<find2(i)<<" "<<i-2*m<<"     papapa ";}//cout<<endl;for(i=1;i<=m;i++){ywcs[o][dui[find2(i)]]=max(ywcs[o][dui[find2(i)]],ywcs2[find2(i)]);//cout<<dui[find2(i)]<<" ";fu[o][i]=dui[find2(i)];ywcs[o][dui[find2(i+3*m)]]=max(ywcs[o][dui[find2(i+3*m)]],ywcs2[find2(i+3*m)]);//cout<<dui[find2(i+m)]<<" ";fu[o][i+m]=dui[find2(i+3*m)];}//cout<<endl;//for(i=1;i<=m;i++)//cout<<find2(i)<<" ";//    cout<<endl;//for(i=1+m;i<=m*2;i++)//cout<<find2(i)<<" ";//cout<<endl;//for(i=1;i<=m;i++)//{//cout<<find(i,o)<<" ";//}//cout<<endl;//for(i=1;i<=m;i++)//{//cout<<ywcs[o][find(i,o)]<<" ";//}//cout<<endl;////for(i=m+1;i<=2*m;i++)//{//cout<<find(i,o)<<" ";//}//cout<<endl;//for(i=1+m;i<=2*m;i++)//{//cout<<ywcs[o][find(i,o)]<<" ";//}////cout<<endl<<endl;////cout<<sz[o]<<"pp"<<endl;}//fu[(N<<2)][14]  ← 基准 void jian(int o,int l,int r){if(l==r){ int i;for(i=1;i<=2*m;i++){fu[o][i]=i;}for(i=1;i<=m;i++){if(tu[l][i]=='+'||tu[l][i]=='-'){if(i-1!=0&&tu[l][i-1]!='.'&&tu[l][i-1]!='|'){int ll=find(i-1,o),rr=find(i,o);if(ll!=rr){fu[o][ll]=rr;ywcs[o][rr]=max(ywcs[o][rr],ywcs[o][ll]);}}if(i+1<=m&&tu[l][i+1]!='.'&&tu[l][i+1]!='|'){int ll=find(i+1,o),rr=find(i,o);if(ll!=rr){fu[o][rr]=ll;ywcs[o][ll]=max(ywcs[o][rr],ywcs[o][ll]);}}}if(tu[l][i]=='O'){if(i+1<=m&&tu[l][i+1]=='O'){int ll=find(i+1,o),rr=find(i,o);if(ll!=rr){fu[o][rr]=ll;ywcs[o][ll]=max(ywcs[o][rr],ywcs[o][ll]);}}if(ywcs[o][find(i,o)]==0){ywcs[o][find(i,o)]=1;sz[o]++;}}}for(i=1;i<=m;i++){int l1=find(i,o),l2=find(m+i,o);fu[o][l2]=l1;ywcs[o][l1]=max(ywcs[o][l1],ywcs[o][l2]);}//for(i=1;i<=m;i++)//cout<<find(i,o)<<" ";////cout<<endl;//for(i=1;i<=m;i++)//cout<<ywcs[o][find(i,o)]<<" ";//////cout<<endl<<endl;////cout<<sz[o]<<endl;return;}int mid=(l+r)>>1;jian(zuo);jian(you);up(o,mid);}void gai(int o,int l,int r){if(l==r){int i;sz[o]=0;for(i=1;i<=m*2;i++){fu[o][i]=i;ywcs[o][i]=0;}for(i=1;i<=m;i++){if(tu[l][i]=='+'||tu[l][i]=='-'){if(i-1!=0&&tu[l][i-1]!='.'&&tu[l][i-1]!='|'){int ll=find(i-1,o),rr=find(i,o);if(ll!=rr){fu[o][ll]=rr;ywcs[o][rr]=max(ywcs[o][rr],ywcs[o][ll]);}}if(i+1<=m&&tu[l][i+1]!='.'&&tu[l][i+1]!='|'){int ll=find(i+1,o),rr=find(i,o);if(ll!=rr){fu[o][rr]=ll;ywcs[o][ll]=max(ywcs[o][rr],ywcs[o][ll]);}}}if(tu[l][i]=='O'){if(i+1<=m&&tu[l][i+1]=='O'){int ll=find(i+1,o),rr=find(i,o);if(ll!=rr){fu[o][rr]=ll;ywcs[o][ll]=max(ywcs[o][rr],ywcs[o][ll]);}}if(ywcs[o][find(i,o)]==0){ywcs[o][find(i,o)]=1;sz[o]++;}}}for(i=1;i<=m;i++){int l1=find(i,o),l2=find(m+i,o);fu[o][l2]=l1;ywcs[o][l1]=max(ywcs[o][l1],ywcs[o][l2]);}//for(i=1;i<=m;i++)//cout<<fu[o][i]<<" ";////cout<<endl;//for(i=1;i<=m;i++)//cout<<ywcs[o][find(i,o)]<<" ";//////cout<<endl<<endl;//cout<<sz[o]<<endl;return;}int mid=(l+r)>>1;if(a<=mid)gai(zuo);else gai(you);up(o,mid);}void wen(int o,int l,int r){if(a<=l&&r<=b){   int i;if(yi==1){memset(ywcs2,0,sizeof(ywcs2));yi=0;int dui[50];//cout<<o<<"pp";//for(i=1+m;i<=2*m;i++)cout<<find(i,o)<<" ";//cout<<endl;//for(i=1+m;i<=2*m;i++)cout<<ywcs[o][find(i,o)]<<" ";//cout<<endl;for(i=1;i<=m;i++){dui[find(i+m,o)]=i;//cout<<find(i+m,o)<<" ";//ywcs2[fu2[i]]=ywcs[o][find(i+m,o)];}            for(i=1;i<=m;i++)            {            ywcs2[dui[find(i+m,o)]]=max(ywcs2[dui[find(i+m,o)]],ywcs[o][find(i+m,o)]);            fu2[i]=dui[find(i+m,o)];}//cout<<endl;////for(i=1;i<=m;i++)cout<<find2(i)<<" ";//cout<<endl;//for(i=1;i<=m;i++)//cout<<ywcs2[find2(i)]<<" ";ans=sz[o];yi=0;}else{ans+=sz[o];//for(i=1;i<=m;i++)cout<<find(i,o)<<" ";//cout<<endl;//for(i=1;i<=m;i++)cout<<ywcs[o][find(i,o)]<<" ";//cout<<endl<<endl;//for(i=1+m;i<=2*m;i++)cout<<find(i,o)<<" ";//cout<<endl;//for(i=1+m;i<=2*m;i++)cout<<ywcs[o][find(i,o)]<<" ";//cout<<endl<<endl;int dui[50];//for(i=1;i<=49;i++)fu2[i]=i;for(i=1;i<=m;i++){    fu2[2*m+i]=find(i,o)+2*m;ywcs2[fu2[m*2+i]]=ywcs[o][find(i,o)];fu2[m*3+i]=find(i+m,o)+2*m;ywcs2[fu2[m*3+i]]=ywcs[o][find(i+m,o)];//cout<<find2(m+i)<<"  "<<find2(m*2+i)<<endl;}//for(i=1;i<=m;i++)cout<<find2(i)<<" ";//cout<<endl;//for(i=1;i<=m;i++)cout<<ywcs2[find2(i)]<<" ";//cout<<endl<<endl;//////for(i=1+2*m;i<=3*m;i++)cout<<find2(i)<<" ";//cout<<endl;//for(i=1+2*m;i<=3*m;i++)cout<<ywcs2[find2(i)]<<" ";//cout<<endl<<endl;//for(i=1+3*m;i<=4*m;i++)cout<<find2(i)<<" ";//cout<<endl;//for(i=1+3*m;i<=4*m;i++)cout<<ywcs2[find2(i)]<<" ";//cout<<endl<<endl;////cout<<ans;for(i=1;i<=m;i++){if(((tu[l-1][i]=='|'||tu[l-1][i]=='+')&&tu[l][i]!='.'&&tu[l][i]!='-')||((tu[l][i]=='|'||tu[l][i]=='+')&&tu[l-1][i]!='.'&&tu[l-1][i]!='-')||(tu[l][i]=='O'&&tu[l-1][i]=='O')){int ll=find2(i),rr=find2(i+2*m);if(ll==rr)continue;     if(ywcs2[rr]==1&&ywcs2[ll]==1)ans--;ywcs2[rr]=max(ywcs2[rr],ywcs2[ll]); fu2[ll]=rr;}}memset(dui,0,sizeof(dui));for(i=1;i<=m;i++){  dui[find2(i+3*m)]=i;}for(i=1;i<=m;i++){ywcs2[dui[find2(i+3*m)]]=ywcs2[find2(i+3*m)];fu2[i]=dui[find2(i+3*m)];}//cout<<endl;//for(i=1;i<=m;i++)cout<<find2(i)<<" ";//            cout<<endl;//for(i=1;i<=m;i++)cout<<ywcs2[find2(i)]<<" ";//cout<<endl<<endl;}return;}int mid=(l+r)>>1;if(a<=mid)wen(zuo);if(b>mid)wen(you);}int main(){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)for(j=1;j<=m;j++){scanf("%c",&ch);while(ch!='|'&&ch!='O'&&ch!='+'&&ch!='-'&&ch!='.')scanf("%c",&ch);tu[i][j]=ch;}jian(1,1,n);scanf("%d",&q);for(i=1;i<=q;i++){scanf("%c",&ch);while(ch!='Q'&&ch!='C')scanf("%c",&ch);scanf("%d%d",&a,&b);if(ch=='Q'){yi=1;ans=0;wen(1,1,n);printf("%d\n",ans);}else {scanf("%c",&ch2);while(ch2!='.'&&ch2!='O'&&ch2!='-'&&ch2!='+'&&ch2!='|')scanf("%c",&ch2);tu[a][b]=ch2;gai(1,1,n);}                    }}



原创粉丝点击