![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//*
题意:问海平面为d时,各个岛屿的income总和
首先要注意d高于格子的高度时,未必被掩了,跟相邻有关。
方法就是类似最短路的先对所有的点重新标号,得到每个点真正被淹没的时间。
用PQ的dijkstra 我用spfa好像有问题,应该我写得有问题
像数据 33333
35553
35153
35553
33333
之后就是对查询排序,然后从高到低,看那些格子升出了水面,这些格子可能会和周围的格子练成岛屿,
这个部分通过并查集来做就好了。
用map<int, int>来记录大小为first的岛屿有second个,以回答查询。
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
细节很多
如:
应该合并到较高位置;
要先查询、每个点高度排序,对每次查询都扫描是否已经合并过就TLE了
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
const int MAXN = 510;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) const int dx[4]= {0,0,1,-1};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) const int dy[4]= {1,-1,0,0};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int R,C,Q;
long long ans[10010];
int height[MAXN][MAXN];
bool visit[MAXN][MAXN];
int fa[MAXN*MAXN],S[MAXN*MAXN];
map<int,int>mp;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) bool chk(int x,int y) {return x>=0&&x<R&&y>=0&&y<C;}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//*
计算1的个数 也可以递推
ones[0]=0
for(int i=1;i<MAXN*MAXN;i++)
ones[i]=ones[i>>1]+(i&1);
*/
inline int calc(int x)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
int tot=0;
while(x)tot+=(x&1),x>>=1;
return tot;
}
int find(int x)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
return fa[x]==x?x:fa[x]=find(fa[x]);
}
void unit(int x,int y)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
x=find(x),y=find(y);
if(x==y)return;
if(--mp[S[x]]==0)mp.erase(S[x]);//注意删除掉!
if(--mp[S[y]]==0)mp.erase(S[y]);
fa[x]=y;
S[y]+=S[x];
mp[S[y]]++;
}
int main()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
while(~scanf("%d%d",&R,&C))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
mp.clear();
memset(visit,0,sizeof(visit));
priority_queue<pair<int,pair<int,int> > >PQ;
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
scanf("%d",&height[i][j]);
if(i==R-1||i==0||j==C-1||j==0)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
visit[i][j]=1;
PQ.push(make_pair(-height[i][j],make_pair(i,j)));
}
}
//dijkstra
while(!PQ.empty())
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int x=PQ.top().second.first,y=PQ.top().second.second;
PQ.pop();
for(int k=0;k<4;k++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int xx=x+dx[k],yy=y+dy[k];
if(chk(xx,yy)&&!visit[xx][yy])
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
visit[xx][yy]=1;//第一次遇到的就是答案了
height[xx][yy]=max(height[xx][yy],height[x][y]);
PQ.push(make_pair(-height[xx][yy],make_pair(xx,yy)));
}
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) /**//*
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
{
printf("%d%c",height[i][j],j==C-1?'\n':' ');
}
*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
scanf("%d",&Q);
vector<pair<int,pair<int,int> > > VQ,VT;
VQ.resize(Q);//
for(int i=0;i<Q;i++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
scanf("%d%d",&VQ[i].first,&VQ[i].second.first);
VQ[i].second.second=i;
}
for(int i=0;i<R;i++)
for(int j=0;j<C;j++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
fa[i*C+j]=i*C+j;
S[i*C+j]=1;
VT.push_back(make_pair(height[i][j],make_pair(i,j)));
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//按照查询的d排序从大到小查询
//然后VT也排序一下,这样就不需多次合并了 用一个指针走下去就行了!
sort(VQ.begin(),VQ.end());
sort(VT.begin(),VT.end());
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
memset(visit,0,sizeof(visit));
vector<pair<int,pair<int,int> > >::reverse_iterator itQ=VQ.rbegin(),itT=VT.rbegin();
for(;itQ!=VQ.rend();itQ++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int d=itQ->first,A=itQ->second.first,id=itQ->second.second;
while(itT!=VT.rend()&&itT->first>d)//
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int x=itT->second.first,y=itT->second.second;
visit[x][y]=1;
mp[1]++;
for(int k=0;k<4;k++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int xx=x+dx[k],yy=y+dy[k];
//向高处(visit[,]=1)合并
if(chk(xx,yy)&&visit[xx][yy])unit(xx*C+yy,x*C+y);
}
itT++;
}
ans[id]=0;
for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
ans[id]+=it->second*(1LL<<calc(it->first&A));
}
}
for(int i=0;i<Q;i++)
printf("%lld\n",ans[i]);
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论
![](/images/xml.gif)
|
|