# 【日常摸鱼】牛客挑战赛2

## C Butterfly

### 链接

https://ac.nowcoder.com/acm/contest/17/C

### 题意

XOOOX
XXOXX
XOXOX
XXOXX
XOOOX

X也是。

XOOX
OXXO
OXXO
XOXX

$n,m\leq 2000$

### 题解

$R(i,j)\geq k-j+1$
$L(i,k)\geq k-j+1$

$R(i,j)+j-1 \geq k \geq j$
$j \geq k+1-L(i,k)$

### $Code$

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL INF=1e18;
const int N=2e5+100;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
void get_min(LL &x,LL y){
if(x>y) x=y;
}
int n,m;
char s[2010];
int mp[2010][2010];
int d[2010][2010],dr[2010][2010],dl[2010][2010];
int L[2010][2010],R[2010][2010];
set<int> S[2];
set<int>::iterator it;
int id[2010],val[2010];
bool cmp(int x,int y){
return val[x]<val[y];
}
int main(){
int x,ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%s",s+1);
for(int j=1;j<=m;++j){
if(s[j]=='X') mp[i][j]=1;
else mp[i][j]=0;
}
}
for(int i=n;i>=1;--i){
for(int j=1;j<=m;++j){
if(!mp[i][j]) d[i][j]=dr[i][j]=dl[i][j]=0;
else{
d[i][j]=dr[i][j]=dl[i][j]=1;
if(i<n) d[i][j]+=d[i+1][j];
if(i<n&&j<m) dr[i][j]+=dr[i+1][j+1];
if(i<n&&j>1) dl[i][j]+=dl[i+1][j-1];
}
}
}
for(int i=n;i>=1;--i){
for(int j=1;j<=m;++j){
L[i][j]=min(d[i][j],dr[i][j]);
R[i][j]=min(d[i][j],dl[i][j]);
}
}
for(int i=1;i<=m;++i) id[i]=i;
for(int i=1;i<=n;++i){
S[0].clear();S[1].clear();
int k;
for(k=1;k<=m;++k){
val[k]=k+1-R[i][k];
}
sort(id+1,id+1+m,cmp);
S[0].insert(0);S[1].insert(0);k=1;
for(int j=1;j<=m;++j){
while(k<=m&&val[id[k]]<=j){
S[(id[k]&1)].insert(id[k]);
++k;
}
it=S[(j&1)].upper_bound(L[i][j]+j-1);
--it;
x=*it;
if(x>=j&&x<=L[i][j]+j-1){
ans=max(ans,x-j+1);
}
}
}
printf("%d\n",ans);
return 0;
}


## D Delete

### 链接

https://ac.nowcoder.com/acm/contest/17/D

### 题意

$n,q\leq 100000,m\leq 200000$

### $Code$

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL INF=1e18;
const int N=2e5+100;
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void print(LL x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
int n,m,S,T;
struct edge{int x,y;LL z;}e[N];
vector<int> L[N],R[N];
int du[N];
int q[N];
int num[N];
LL ds[N],dt[N];
LL mn[N<<1];
void upd(int l,int r,int id,LL w,int lq,int rq){
if(lq==l&&rq==r){
mn[id]=min(mn[id],w);
return;
}
int mid=(l+r)>>1;
if(lq>mid) upd(mid+1,r,id<<1|1,w,lq,rq);
else if(rq<=mid) upd(l,mid,id<<1,w,lq,rq);
else{
upd(l,mid,id<<1,w,lq,mid);
upd(mid+1,r,id<<1|1,w,mid+1,rq);
}
return;
}
LL ask(int l,int r,int id,int x){
if(l==r) return mn[id];
int mid=(l+r)>>1;
}
int main(){
for(int i=1;i<=m;++i){
++du[e[i].y];
R[e[i].x].push_back(i);
L[e[i].y].push_back(i);
}
int l=1,r=0,x,y;edge ed;LL ans;
for(int i=1;i<=n;++i) if(!du[i]) q[++r]=i;
while(l<=r){
x=q[l++];
for(int i=0;i<R[x].size();++i){
y=e[R[x][i]].y;
--du[y];
if(!du[y]) q[++r]=y;
}
}
for(int i=1;i<=n;++i){
num[q[i]]=i;
}
for(int i=1;i<=n;++i){
ds[i]=dt[i]=INF;
}
ds[S]=0;
for(int i=1;i<=r;++i){
for(int j=0;j<R[q[i]].size();++j){
ed=e[R[q[i]][j]];
ds[ed.y]=min(ds[ed.y],ds[ed.x]+ed.z);
}
}
dt[T]=0;
for(int i=r;i>=1;--i){
for(int j=0;j<L[q[i]].size();++j){
ed=e[L[q[i]][j]];
dt[ed.x]=min(dt[ed.x],dt[ed.y]+ed.z);
}
}
for(int i=1;i<(N<<1);++i) mn[i]=INF;

for(int i=1;i<=m;++i){
ans=ds[e[i].x]+e[i].z+dt[e[i].y];
if(ans<INF&&num[e[i].x]+1<=num[e[i].y]-1)
upd(1,n,1,ans,num[e[i].x]+1,num[e[i].y]-1);
}
while(Q--){
if(num[x]<num[S]||num[x]>num[T]){
if(ds[T]==INF)puts("-1");
else printf("%lld\n",ds[T]);
continue;
}
if(ans==INF) puts("-1");
else printf("%lld\n",ans);
}
return 0;
}


## E Mod

posted @ 2021-02-05 12:03  Iscream-2001  阅读(38)  评论(0编辑  收藏  举报
/* */