社区讨论
求助卡常
P3684[CERC2016] 机棚障碍 Hangar Hurdles参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lo7sfj60
- 此快照首次捕获于
- 2023/10/27 07:00 2 年前
- 此快照最后确认于
- 2023/10/27 07:00 2 年前
缩点后树剖+ST表 TLE on #7 #9
有什么办法吗/kk
CPP有什么办法吗/kk
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
#define R register
struct EDGE{
int v,w,last;
}Edge[1000005];
struct EDGE2{
int u,v,w;
}Edge2[1000005];
struct NODE{
int x,y;
};
int n;
int m;
int q;
int nn;
int cnt;
int ecnt;
int a[500005];
int p[500005];
int fa[500005];
int id[500005];
int in[500005];
int top[500005];
int dep[500005];
int son[500005];
int sig[500005];
int size[500005];
int b[1005][1005];
char s[1005][1005];
int st[500005][21];
int num[1005][1005];
int sum[1005][1005];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
inline void input(int &x){
x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
}
void write(int x){
if (x<10){
putchar((char)(x+'0'));return;
}
write(x/10);
putchar((char)(x%10+'0'));
}
inline void output(int x,char c){
if (x<0) {putchar('-');x*=-1;}
write(x);putchar(c);
}
inline void input2(int i){
char c=getchar();
while(c!='.'&&c!='#') c=getchar();
int l=0;
while(c=='.'||c=='#'){
s[i][++l]=c;
sum[i][l]=sum[i][l-1]+sum[i-1][l]-sum[i-1][l-1]+(c=='#');
c=getchar();
}
}
inline int min(int a,int b){
return a<b?a:b;
}
bool cmp(EDGE2 _1,EDGE2 _2){
return _1.w>_2.w;
}
inline void swap(int &a,int &b){
int t=a;a=b;b=t;
}
inline void init(){
ecnt=0;
for (R int i(1);i<=nn;++i){
p[i]=-1;
}
}
inline void insert(int u,int v,int w){
Edge[++ecnt].v=v;
Edge[ecnt].w=w;
Edge[ecnt].last=p[u];
p[u]=ecnt;
}
inline void init2(){
for (R int i(1);i<=nn;++i){
sig[i]=i;
}
}
int get(int x){
return x==sig[x]?x:sig[x]=get(sig[x]);
}
inline bool check(int x,int y,int l){
int ux=x-l,dx=x+l;
int ly=y-l,ry=y+l;
if (ux<1||dx>n||ly<1||ry>n) return false;
int res=sum[dx][ry]-sum[ux-1][ry]-sum[dx][ly-1]+sum[ux-1][ly-1];
return !res;
}
inline void get_binary(int x,int y){
int l=0,r=n;
int res=-1;
while(l<=r){
int mid=(l+r)>>1;
if (check(x,y,mid)){
l=mid+1;res=mid;
}
else{
r=mid-1;
}
}
b[x][y]=res<<1|1;
}
inline void bfs(int x,int y){
++nn;
queue<NODE> q;
q.push(NODE{x,y});
// printf("%d:%d %d\n",nn,x,y);
while(!q.empty()){
NODE u=q.front();q.pop();
int x=u.x,y=u.y;
num[x][y]=nn;
for (R int i(0);i<4;++i){
int nx=x+dx[i];
int ny=y+dy[i];
if (b[nx][ny]==b[x][y]&&(!num[nx][ny])){
q.push(NODE{nx,ny});
}
}
}
}
inline void Kruskal(){
init();init2();
sort(Edge2+1,Edge2+m+1,cmp);
for (R int i(1);i<=m;++i){
int u=Edge2[i].u;
int v=Edge2[i].v;
int w=Edge2[i].w;
int fu=get(u),fv=get(v);
if (fu!=fv){
sig[fu]=fv;
// printf("%d %d:%d\n",u,v,w);
insert(u,v,w);insert(v,u,w);
}
}
}
inline void build(){
for (R int i=1;i<=nn;i++){
st[i][0]=a[i];
}
for (R int j(1);(1<<j)<=nn;++j){
for (R int i(1);i<=nn;++i){
if (i+(1<<j)-1>nn) break;
st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
inline int query(int l,int r){
int x=(int)log2(1.0*(r-l+1));
return min(st[l][x],st[r-(1<<x)+1][x]);
}
void dfs1(int u,int f){
// printf("%d %d\n",u,f);
fa[u]=f;dep[u]=dep[f]+1;size[u]=1;
for (R int i(p[u]);i!=-1;i=Edge[i].last){
int v=Edge[i].v;
int w=Edge[i].w;
if (v==f) continue;
dfs1(v,u);size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
in[v]=w;
}
}
void dfs2(int u,int tp){
top[u]=tp;id[u]=++cnt;a[cnt]=in[u];
if (son[u]) dfs2(son[u],tp);
for (R int i(p[u]);i!=-1;i=Edge[i].last){
int v=Edge[i].v;
if (v==son[u]||v==fa[u]) continue;
dfs2(v,v);
}
}
inline int query_tree(int u,int v){
int res=inf;
while(top[u]!=top[v]) {
if (dep[top[u]]<dep[top[v]]) swap(u,v);
res=min(res,query(id[top[u]],id[u]));
u=fa[top[u]];
}
if (u!=v){
if (dep[u]>dep[v]) swap(u,v);
res=min(res,query(id[u]+1,id[v]));
}
return res;
}
int main(){
input(n);
for (R int i(1);i<=n;++i){
input2(i);
}
for (R int i(1);i<=n;++i){
for (R int j(1);j<=n;++j){
get_binary(i,j);
// output(b[i][j],' ');
}
// putchar('\n');
}
// putchar('\n');
for (R int i(1);i<=n;++i){
for (R int j(1);j<=n;++j){
if (s[i][j]=='#') continue;
if (!num[i][j]){
bfs(i,j);
}
}
}
/*
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
output(num[i][j],' ');
}
putchar('\n');
}
//*/
for (R int i=(1);i<=n;++i){
for (R int j=(1);j<=n;++j){
if (!num[i][j]) continue;
for (R int k(0);k<2;++k){
int ni=i+dx[k];
int nj=j+dy[k];
if (!num[ni][nj]) continue;
if (num[i][j]==num[ni][nj]) continue;
Edge2[++m]=EDGE2{num[i][j],num[ni][nj],min(b[i][j],b[ni][nj])};
}
}
}
Kruskal();
for (R int i(1);i<=nn;++i){
if (!id[i]){
dfs1(i,0);dfs2(i,i);
}
}
build();
input(q);
while(q--){
int x1,y1,x2,y2;
input(x1);input(y1);input(x2);input(y2);
if (num[x1][y1]==num[x2][y2]) output(b[x1][y1],'\n');
else output(query_tree(num[x1][y1],num[x2][y2]),'\n');
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...