2019.7.12 义乌模拟赛 T3 go
题面传送门
看到这个权值计算式直接一脸懵逼。
然后枚举了所有情况发现权值都是\(x_2^2y_2^2-x1^2y1^2-x2^2-y2^2+\sum\limits_{(x_i,y_i)\in S}{x_i^2+y_i^2}\)
这就要我们令后面那个东西最小。
因为每走一步和是一样的所以根据基本不等式我们要让他尽可能贴近\(y=x\)那条线。
然后直接分类讨论即可,注意有些是要在\(y=x\)上折返的。
封装函数会好写一点
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 100000
#define M 500000
#define mod 998244353
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int T,flag;ll ans,tot,pus,n,m,x,y;
I void swap(int &x,int &y){x^=y^=x^=y;}
I ll mpow(ll x,int y=mod-2){ll ans=1;while(y) (y&1)&&(ans=ans*x%mod),y>>=1,x=x*x%mod;return ans;}const ll inv=mpow(6);
I ll CQ(ll x){return x*(x+1)%mod*(2*x+1)%mod*inv%mod;}
I ll QU(ll x,ll y){return (CQ(y)-CQ(x-1)+mod)%mod;}
I ll Query(ll x,ll y,ll z){return x*x%mod*(z-y+1)%mod+QU(y,z);}//(y,x)->(z,x)|(x,y)->(x,z)
I ll Queryxy(ll x,ll y){return QU(x,y)*2+QU(x,y-1)+QU(x+1,y);}//(x,x)->(y,y)
int main(){
// freopen("go.in","r",stdin);freopen("go.out","w",stdout);
re int i;scanf("%d",&T);while(T--){
scanf("%lld%lld%lld%lld",&n,&m,&x,&y);flag=0;if(n>x) swap(n,x),swap(m,y),flag=1;
if(m>=n){
if(y>=x){
if(m<x) ans=Query(m,n,m-1)+Queryxy(m,x)+Query(x,x+1,y);
else ans=(m>y)?(Query(n,y,m)+Query(y,n+1,x)):(Query(m,n,x)+Query(x,m+1,y));
}
else ans=m>y?(Query(n,y,m)+Query(y,n+1,x)):(Query(m,n,m-1)+Queryxy(m,y)+Query(y,y+1,x));//printf(" %lld\n",Query(m,n,x)+Query(x,m+1,y));
}
else{
if(y>=x) ans=Query(n,m,n-1)+Queryxy(n,x)+Query(x,x+1,y);
else{
if(y>n) ans=Query(n,m,n-1)+Queryxy(n,y)+Query(y,y+1,x);
else ans=(m>y)?(Query(n,y,m)+Query(y,n+1,x)):(Query(n,m,y)+Query(y,n+1,x));
}
}
if(flag) swap(n,x),swap(m,y);ans+=x*x%mod*y%mod*y%mod-n*n%mod*m%mod*m%mod-x*x%mod-y*y%mod;printf("%lld\n",(ans%mod+mod)%mod);
}
}