P14645 [POI 2025/2026 #1] 传话 / Dostawy Solution
题解
我们发现贪心是好想的,只需考虑每个点所到达的最短时间,按照时间大小从大往小排序即可。
因为不同出发的点都带有权值(即它的出发时间),这个东西是不好维护的,但我们可以发现它的出发时间每次最多只会
我们可以用线段树维护区间最大值,这样查询是
考虑对于时间
我们发现加入与删除的性质相同,这里提供加入的解法。
我们发现对于完全
但对于
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <queue>
#include <set>
#ifdef _WIN32
#define getchar _getchar_nolock
#define putchar _putchar_nolock
#else
#define getchar getchar_unlocked
#define putchar putchar_unlocked
#endif
#define pll pair<ll,ll>
#define pld pair<ld,ld>
typedef long long ll;
typedef long double ld;
typedef __int128 i128;
namespace io {
using namespace std;
template <typename T> void debug (T x) {
cerr<<x<<'\n';
}
template <typename T> void debuglen (T x) {
cerr<<x<<' ';
}
template <typename T,typename...Args> void debug (T x,Args...args) {
cerr<<x<<' ';
debug(args...);
}
template <typename T> void debug (T*lt,T*rt) {
ll len=rt-lt;
for (ll i=0;i<len;i++) {
debuglen(*(lt+i));
}
cerr<<'\n';
}
inline ll read () {
char x=getchar();
ll ans=0,f=1;
while (x<'0'||x>'9') {
if (x=='-') {
f=-1;
}
x=getchar();
}
while (x>='0'&&x<='9') {
ans=(ans<<1)+(ans<<3);
ans+=(x^'0');
x=getchar();
}
return ans*f;
}
void print (ll x) {
if (x<0) {
x=-x;
putchar('-');
}
if (x>=10) {
print(x/10);
}
putchar(x%10+'0');
}
}
using namespace io;
const ll N=1e3+5,M=4e6+5,mod=1e9+7,inf=2e18;
const ld eps=1e-6;
ll dx[]={0,1,0,-1,0},dy[]={0,0,1,0,-1};
ll n,q,dis[N][N],num[M];
bool vis[N][N],bis[N][N];
string s;
queue<pll> pq;
struct BIT {
ll t[M];
inline ll lowbit (ll x) {
return x&(-x);
}
inline void add (ll x,ll val) {
x=n*n-x+1;
while (x<=n*n) {
t[x]+=val;
x+=lowbit(x);
}
}
inline ll query (ll x) {
x=n*n-x+1;
ll ans=0;
while (x) {
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
} trl;
struct Segtree {
ll t[M],lt[M];
inline void push_up (ll pos) {
t[pos]=max(t[pos<<1],t[pos<<1|1]);
}
inline void push_down(ll pos) {
if(t[pos<<1]) {
t[pos<<1]+=lt[pos];
}
if(t[pos<<1|1]) {
t[pos<<1|1]+=lt[pos];
}
lt[pos<<1]+=lt[pos];
lt[pos<<1|1]+=lt[pos];
lt[pos]=0;
}
void addl (ll pos,ll l,ll r,ll L,ll R,ll val) {
if (L<=l&&r<=R) {
if (t[pos]) {
t[pos]+=val;
}
lt[pos]+=val;
return ;
}
ll mid=(l+r)>>1;
push_down(pos);
if (L<=mid) {
addl(pos<<1,l,mid,L,R,val);
}
if (R>mid) {
addl(pos<<1|1,mid+1,r,L,R,val);
}
push_up(pos);
}
void add (ll pos,ll l,ll r,ll x) {
if (l==r) {
t[pos]=0;
if (num[l]) {
t[pos]=l+trl.query(l);
}
return ;
}
ll mid=(l+r)>>1;
push_down(pos);
if (x<=mid) {
add(pos<<1,l,mid,x);
}
else {
add(pos<<1|1,mid+1,r,x);
}
push_up(pos);
}
} tr;
void bfs () {
dis[1][1]=0;
pq.push({1,1});
while (!pq.empty()) {
pll d=pq.front();
pq.pop();
ll x=d.first,y=d.second;
for (ll i=1;i<=4;i++) {
ll xx=x+dx[i],yy=y+dy[i];
if (vis[xx][yy]||xx>n||xx<1||yy>n||yy<1) {
continue;
}
if (dis[xx][yy]>dis[x][y]+1) {
dis[xx][yy]=dis[x][y]+1;
pq.push({xx,yy});
}
}
}
}
inline void add (ll pos) {
num[pos]++;
trl.add(pos,1);
tr.add(1,1,n*n,pos);
if (pos!=1) {
tr.addl(1,1,n*n,1,pos-1,1);
}
}
inline void del (ll pos) {
num[pos]--;
trl.add(pos,-1);
tr.add(1,1,n*n,pos);
if (pos!=1) {
tr.addl(1,1,n*n,1,pos-1,-1);
}
}
inline void solve () {
n=read(),q=read();
for (ll i=1;i<=n;i++) {
cin>>s;
for (ll j=1;j<=n;j++) {
if (s[j-1]=='Z'||s[j-1]=='F') {
bis[i][j]=1;
}
if (s[j-1]=='#') {
vis[i][j]=1;
}
dis[i][j]=inf;
}
}
bfs();
for (ll i=1;i<=n;i++) {
for (ll j=(i==1?2:1);j<=n;j++) {
if (bis[i][j]) {
add(dis[i][j]);
}
}
}
print(max(0ll,tr.t[1]-1));
puts("");
while (q--) {
ll x=read(),y=read();
if (bis[x][y]) {
del(dis[x][y]);
}
else {
add(dis[x][y]);
}
bis[x][y]^=1;
print(max(0ll,tr.t[1]-1));
puts("");
}
}
int main () {
// freopen("dostawy.in","r",stdin);
// freopen("dostawy.out","w",stdout);
ll T=1;
// T=read();
while (T--) {
solve();
}
return 0;
}