mxqz,调了3天没调出来
查看原帖
mxqz,调了3天没调出来
555345
Hell0_W0rld楼主2024/9/23 20:26

rt

#include<atcoder/math>
#define ll long long
#define lll __int128_t
#define ull unsigned long long
#define ld long double
#define rep(i,l,r) for(register ll i=(l);i<=(r);++i)
#define Rep(i,l,r) for(register ll i=(r);i>=(l);--i)
#define all(x) x.begin(),x.end()
#define Set(x,y) memset(x,y,sizeof(x))
#define Cpy(x,y) memcpy(x,y,sizeof(x))
#define cll const long long
using namespace std;
template<class T>
void death(T s){cout<<s<<endl;exit(0);}
cll N=200009;
struct frac{
	lll u,d;
	frac(lll _u=0,lll _d=1){u=_u/__gcd(_u,_d),d=_d/__gcd(_u,_d); if(d<0)d=-d,u=-u; assert(d!=0); }
	bool operator<(const frac&x)const{return u*x.d<x.u*d;}
	bool operator>(const frac&x)const{return u*x.d>x.u*d;}
	bool operator==(const frac&x)const{return u==x.u&&d==x.d;}
	bool operator!=(const frac&x)const{return u!=x.u||d!=x.d;}
	frac operator+(const frac&x)const{return frac(u*x.d+d*x.u,d*x.d);}
	frac operator-(const frac&x)const{return frac(u*x.d-d*x.u,d*x.d);}
	frac operator/(const frac&x)const{assert(x.u!=0); return frac(u*x.d,d*x.u);}
};
lll flor(frac x){return x.u/x.d;}
lll cei(frac x){return (x.u-1)/x.d+1;}
bool integ(frac x){return x.d==1;}
struct Line{
	frac b,k; ll id;
	bool operator<(const Line&x)const{return k>x.k || k==x.k&&b>x.b;}
	#define b(u) lines[u].b 
	#define k(u) lines[u].k
}lines[N];
struct HalfPlane{ll a,b,c;} p[N];//ax+by<=c
frac X(ll u,ll v){
	return (b(v)-b(u))/(k(u)-k(v));
} 
ll n,q[N],tno;
const ll MOD=998244353;
void clr(){
	rep(i,0,tno){
		lines[i]=(Line){frac(),frac(),0};
		p[i]=(HalfPlane){0,0,0};
		q[i]=0;
	}
	n=tno=0;
}
void solve(){
	cin>>n; tno=n;
	rep(i,1,n){
		ll a,b,c;
		cin>>a>>b>>c;
		c--;
		lines[i]=(Line){frac(c,b),frac(-a,b),i};
		p[i]=(HalfPlane){a,b,c};
	}
	sort(lines+1,lines+1+n);
	ll l=1,r=1;
	rep(i,1,n-1)if(k(i)==k(i+1))i--,n--;
	rep(i,1,n){
		while(r-l>=2&&X(i,q[r-1])<X(q[r-1],q[r-2])) r--;
		q[r++]=i;
	}
	rep(i,1,r-1)lines[i]=lines[q[i]];
	n=r-1;
	ll ans=0;
	rep(l,1,n){
		ll id=lines[l].id;
		lll x0=1,x1=flor(X(l,0));
		if(l!=1){
			frac a=X(l,l-1);
			x0=cei(a)+integ(a);
		}
		if(l!=n){
			frac a=X(l,l+1);
			x1=flor(a);
		}
		if(x0<1)x0=1;
		x1=min(x1,flor(X(l,0)));
		if(x1<x0)continue;
		/*
		对于直线y=kx+b x in [l,r]
		ax+by<=c
		即求 by<=c-ax的和
		求sigma[l...r] floor((-ax+c)/b)
		-> sigma[0...r-l] floor((-a(x+l)+c)/b)
		-> sigma[0...r-l] floor(( (-a)x+(c-a*l) )/b) 
		*/ 
		ll a=p[id].a,b=p[id].b,c=p[id].c;
		(ans+=atcoder::floor_sum(x1-x0+1,b,-a,c-a*x0))%=MOD;
	}
	cout<<ans<<endl;
}
int main(){
	ll T;
	cin>>T;
	while(T--){
		clr();
		solve();
	}
	return 0;
}

思路是求下凸包,然后用类欧和交点坐标求出具体下面有几个点

2024/9/23 20:26
加载中...