The 2025 ICPC Asia East Continent Online Contest (I)
C
- 依次考虑 \(1\sim n\) 的每一个数,如果它的颜色在之前出现过,那么一定能够给答案 \(-1\);
- 每个位置一定染成它的相邻前一个位置,这样能影响最少的区间,是最优的;
- 把区间按照右端点为第一关键字,左端点为第二关键字排序,每次取距离 \(l\) 最近的且相邻颜色不同的点,将它染色。
const int N=2e5+10;
struct sgt{
int tot=0;
struct node{
int ls,rs,sum;
node(){ls=rs=sum=0;}
}t[N*30];
sgt(){tot=0;}
void init()
{
for(int i=0;i<=tot;i++)t[i].ls=t[i].rs=t[i].sum=0;
tot=0;
}
void modify(int &p,int l,int r,int x,int d)
{
if(!p)p=++tot;
if(l==r)return t[p].sum+=d,void();
int mid=(l+r)/2;
if(x<=mid)modify(t[p].ls,l,mid,x,d);
else modify(t[p].rs,mid+1,r,x,d);
t[p].sum=t[t[p].ls].sum+t[t[p].rs].sum;
}
int query(int p,int l,int r,int L,int R)
{
if(!p)return 0;
if(L<=l&&r<=R)return t[p].sum;
int mid=(l+r)/2,ans=0;
if(L<=mid)ans+=query(t[p].ls,l,mid,L,R);
if(R>mid)ans+=query(t[p].rs,mid+1,r,L,R);
return ans;
}
}T;
struct seg{
int l,r;
}a[N];
bool cmp(seg x,seg y){return x.r==y.r?x.l<y.l:x.r<y.r;}
void sol()
{
int m=read(),n=read(),rt=0;
for(int i=1;i<=m;i++)a[i].l=read(),a[i].r=read();
sort(a+1,a+m+1,cmp);
T.init();
int Ans=n;
for(int i=1;i<=m;i++)
{
if(a[i].l==a[i].r)continue;
int pos=0,L=a[i].l,R=a[i].r-1;
while(L<=R)
{
int mid=(L+R)/2;
if(T.query(rt,1,n,L,mid)==mid-L+1)L=mid+1;
else pos=mid,R=mid-1;
}
if(pos)T.modify(rt,1,n,pos,1),Ans--;
// printf("[%d, %d], pos=%d\n",a[i].l,a[i].r,pos);
}
printf("%d\n",Ans);
}
int main()
{
int T=read();
while(T--)sol();
return 0;
}
J
曼哈顿转切比雪夫,两维独立
考虑一维怎么做,直接枚举点,钦定在最左边,再枚举其位置即可
\(\mathcal O(NM)\)
const int N=2e5+10,mod=998244353,zzt=3e5;
int fac[zzt*2+10],ifac[zzt*2+10];
int qpow(int a,int n)
{
int ans=1;
while(n)
{
if(n&1)ans=1ll*a*ans%mod;
a=1ll*a*a%mod;
n>>=1;
}
return ans;
}
int binom(int n,int m){return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod;}
int x[N],y[N];
int calc(int d,int s)//distance, steps required
{
if(d%2!=s%2||d>s)return 0;
int tmp=(s+d)/2;
return binom(s,tmp);
}
int n,m,k;
void Add(int &x,int y){x+=y;if(x>=mod)x-=mod;}
void Sub(int &x,int y){x-=y;if(x<0)x+=mod;}
int sum[N<<2],mul1[N<<2][60],mul2[N<<2][60];//1:k, 2:k-1
int calc(int a[])
{
if(!k)
{
int Ans=0;
for(int p=-zzt;p<=zzt;p++)
{
int now=1;
for(int i=1;i<=n;i++)now=1ll*now*calc(abs(a[i]-p),m);
Add(Ans,now);
}
return Ans;
}
else
{
for(int i=1;i<=n;i++)
{
for(int p=-zzt;p<=zzt;p++)sum[p+zzt]=calc(abs(a[i]-p),m);
for(int p=-zzt+1;p<=zzt+k;p++)Add(sum[p+zzt],sum[p+zzt-1]);
for(int p=-zzt;p<=zzt;p++)
{
mul1[p+zzt][i]=sum[p+zzt+k];
mul2[p+zzt][i]=sum[p+zzt+k-1];
if(p!=-zzt)Sub(mul1[p+zzt][i],sum[p+zzt-1]),Sub(mul2[p+zzt][i],sum[p+zzt-1]);
}
}
for(int p=-zzt;p<=zzt;p++)
{
for(int i=2;i<=n;i++)mul1[p+zzt][i]=1ll*mul1[p+zzt][i]*mul1[p+zzt][i-1]%mod;
for(int i=n-1;i>=1;i--)mul2[p+zzt][i]=1ll*mul2[p+zzt][i]*mul2[p+zzt][i+1]%mod;
}
int Ans=0;
for(int i=1;i<=n;i++)
{
for(int p=a[i]-m;p<=a[i]+m;p++)
{
int now=calc(abs(a[i]-p),m);
if(i>1)now=1ll*now*mul1[p+zzt][i-1]%mod;
if(i<n)now=1ll*now*mul2[p+zzt+1][i+1]%mod;
Add(Ans,now);
}
}
return Ans;
}
}
int main()
{
fac[0]=1;
for(int i=1;i<=zzt*2;i++)fac[i]=1ll*fac[i-1]*i%mod;
ifac[zzt*2]=qpow(fac[zzt*2],mod-2);
for(int i=zzt*2-1;i>=0;i--)ifac[i]=1ll*(i+1)*ifac[i+1]%mod;
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++)
{
x[i]=read(),y[i]=read();
int xx=x[i],yy=y[i];
x[i]=xx+yy,y[i]=xx-yy;
}
int Ans=1ll*calc(x)*calc(y)%mod;
printf("%d\n",Ans);
return 0;
}

浙公网安备 33010602011771号