P2132 -- Zrn神犇之一起来看流星雨
时间限制:1000MS
内存限制:131072KB
Description
Zrn神犇带着妹纸来到异度空间看流星雨。
那儿有个矩形的星盘,一共有N*M格,流星雨都会落在那里。只是,那里的流星雨很奇特,都是很有节奏地、成排成排地落下的。每个时刻都会落下一排的流星,它们落在星盘上,形成了一个一个星群。
而Zrn神犇和妹纸对于星群的定义是不一样的。Zrn神犇认为,一颗星星和它周围的四个格子里的星星属于同一个星群。而妹纸认为,一颗星星和它周围的八个格子里的星星都属于同一个星群。
比如在第一个时刻,星盘上可能是这样的:
此时Zrn神犇和妹纸都看到了2个星群。
接着又落下了一排星星:
此时在Zrn神犇看来有2个星群,而在妹纸眼中只有1个星群。
又落下了第三排星星:
此时Zrn神犇看到的有3个星群,而在妹纸眼中依然只有一个星群。
妹纸看得有些累了,便靠在Zrn神犇的身上。Zrn神犇也伸出手臂,轻轻搂住她。
这时妹纸发话了:“你知道在任意时刻我们看到的星群数量各是多少吗?说不出来你亲我一下!”
Zrn神犇当然不想说啦!所以你就来算一下吧。
Input Format
第一行两个整数N,M
接下来一个N行M列的矩阵,表示在第N个时刻星盘上的布局,“*”表示该格有星星,“ ”表示该格没有星星。
下面一行一个整数Q,代表询问个数。
接下来Q行,每行一个正整数T,表示询问第T个时刻。
Output Format
输出Q行,对于每个T,输出一行两个整数,分别为在第T个时刻Zrn神犇看到的星群数量和妹纸看到的星群数量。
Sample Input
3 3 * * ** * 3 1 2 3
Sample Output
2 2 2 1 3 1
Hint
# | N | M | Q |
---|---|---|---|
1 | 10 | 10 | 1 |
2 | 2000 | 2000 | 1 |
3 | 3000 | 2000 | 2 |
4 | 50 | 50 | 50 |
5 | 40 | 40 | 5000 |
6 | 50 | 50 | 10000 |
7 | 1000 | 1000 | 50000 |
8 | 2000 | 2000 | 100000 |
9 | 5000 | 200 | 50000 |
10 | 20000 | 200 | 100000 |
保证1≤T≤N。
【题解】
就是并查集了,妹子的开一个,Zrn的开一个。
然后输入的时候进行维护,维护每个时段。
滚动数组进行优化。
并查集的时候我开同一个来进行操作=-=竟然T了!!!!!
然后我就分开来写,AC了=-=
我们需要分开来来优化。。。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int f[2][40000010],r[20001][2001],t[2],n,m,ans[2][20001],k; 4 int getf0(int x) {return f[0][x]==x?x:f[0][x]=getf0(f[0][x]);} 5 int getf1(int x) {return f[1][x]==x?x:f[1][x]=getf1(f[1][x]);} 6 void join0(int a,int b) { 7 int fa=getf0(a),fb=getf0(b); 8 if(fa!=fb) f[0][fa]=fb,t[0]--; 9 } 10 void join1(int a,int b) { 11 int fa=getf1(a),fb=getf1(b); 12 if(fa!=fb) f[1][fa]=fb,t[1]--; 13 } 14 int read() { 15 int x=0; int fx=1; 16 char ch=getchar(); 17 while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) fx=-1; ch=getchar();} 18 while(ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} 19 return x*fx; 20 } 21 int main() { 22 n=read(),m=read(); 23 for (int i=0;i<n;++i) { 24 for(int j=0;j<m;++j) { 25 char c=getchar(); 26 if(c==‘*‘) { 27 ++k; 28 f[0][k]=f[1][k]=r[i][j]=k; 29 t[0]++,t[1]++; 30 if(j&&r[i][j-1]) { 31 join0(r[i][j],r[i][j-1]); 32 join1(r[i][j],r[i][j-1]); 33 } 34 if(i&&r[i-1][j]) { 35 join0(r[i][j],r[i-1][j]); 36 join1(r[i][j],r[i-1][j]); 37 } 38 if(i&&j&&r[i-1][j-1]) join1(r[i][j],r[i-1][j-1]); 39 if(i&&j+1<m&&r[i-1][j+1]) join1(r[i][j],r[i-1][j+1]); 40 } 41 } 42 getchar(); 43 ans[0][i]=t[0]; 44 ans[1][i]=t[1]; 45 } 46 int T,rx; 47 T=read(); 48 while(T--) { 49 rx=read();rx--; 50 printf("%d %d\n",ans[0][rx],ans[1][rx]); 51 } 52 return 0; 53 }
最后终于最变态的点优化到0.92s,还加了读入优化,不然就0.98s了吧=-=