洛谷$P5444\ [APIO2019]$奇怪装置 数论

正解:数论

解题报告:

传送门$QwQ$

我好像当初考的时候这题爆零了,,,部分分都没想到,,,我真的好菜$kk$

考虑如果在$t_1,t_2$两个时刻有$x_1=x_2,y_1=y_2$是什么情况$QwQ$?

那就有$\begin{cases}t_1+[\frac{t_1}{B}]\equiv t_2+[\frac{t_2}{B}](\mod A)\\t_1\equiv t_2(\mod B)\end{cases}$.

不妨设$t_2=t_1+B\cdot t$,代入得$t_1+[\frac{t_1}{B}]\equiv t_1+B\cdot k+[\frac{t_1+B\cdot k}{B}](\mod A)$,即$k(B+1)\equiv 0(\mod A)$

解得$\frac{A}{gcd(A,B+1)}|k$.即将$mod\ B$相等的提出来,发现每$\frac{A}{gcd(A,B+1)}$一循环.又因为$mod\ B$的结果有$B$个,所以总的循环节长度为$len=\frac{A\cdot B}{gcd(A,B+1)}$.

所以把$l,r$取模后变成若干条线段,然后现在询问$[0,len)$覆盖了多少个点.昂这个不差分下就行了嘛,$over$

 

#include
using namespace std;
#define il inline
#define fi first
#define sc second
#define ll long long
#define gc getchar()
#define mp make_pair
#define P pair
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ll i=x;i<=y;++i)
#define my(i,x,y) for(ll i=x;i>=y;--i)

const int N=1e6+10;
const ll inf=1e18;
ll n,A,B,len,l[N],r[N],sum,dat,lst,as;
multiset

S; il ll read() { rc ch=gc;ll x=0;rb y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')ch=gc,y=0; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} il void ad(ll x,ll y){S.insert(mp(x,-1));S.insert(mp(y,1));} int main() { //freopen("5444.in","r",stdin);freopen("5444.out","w",stdout); n=read();A=read();B=read();len=A/gcd(A,B+1)*B;rp(i,1,n){l[i]=read(),r[i]=read();sum+=r[i]-l[i]+1;} if(A/gcd(A,B+1)>inf/B)return printf("%lld\n",sum),0; rp(i,1,n) { if(r[i]-l[i]>=len)return printf("%lld\n",len),0;;//printf("l=%lld r=%lld len=%lld\n",r[i],l[i],len); if(l[i]/len!=r[i]/len)ad(l[i]%len,len-1),ad(0,r[i]%len);else ad(l[i]%len,r[i]%len); } multiset

::iterator it=S.begin(); while(it!=S.end()){P tmp=*it;if(!dat)lst=tmp.fi;dat-=tmp.sc;if(!dat)as+=tmp.fi-lst+1;++it;} printf("%lld\n",as); return 0; }

View Code

 

 

 

你可能感兴趣的:(洛谷$P5444\ [APIO2019]$奇怪装置 数论)