codevs1213(扩欧,求区间内解的数量)
2016-08-23 10:55
363 查看
求区间内解的数量这一类的题,总是感觉会有很多的细节考虑的不够全。然后就被各种数据搞。。。
虽然这题卡数据,需要吐槽,但是也学了一些方法
注释中~
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
ll n,x,y;
ll a,b,c,q,p,r,s;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if (b==0) {d=a;x=1;y=0;return;}
exgcd(b,a%b,d,y,x);y-=x*(a/b);
}
ll bdfc(ll a,ll b,ll c)
{
ll d;
exgcd(a,b,d,x,y);
if (c%d) return 0;
x=x*(c/d);
//y=y*(c/d);
int ka=a/d;
int kb=b/d;
if (x>p)
{
int t=(x-p)/kb;//如果要求一个区间的解的数量,首先想要到区间左端之前,但是直接while会被卡TLE,所以,既然只有减法,就可以改成除一下就好
x-=kb*t;//当然要判断一下,最后是否除到下面了,所以再减一下。。
if (x>p) x-=kb;
}
if (b) y=(c-a*x)/b;else y=0;
ll ans=0;
while (x<=q)
{
if (x>=p&&x<=q&&y>=r&&y<=s) ans++;
x+=kb;
y-=ka;
}
return ans;
}
int main()
{
scanf("%lld",&n);
while (n--)
{
scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&p,&q,&r,&s);
if(a==0&&b==0&&c==0)
{
if(q>=p&&s>=r)
cout<<(q-p+1)*(s-r+1)<<endl;
else cout<<"0"<<endl;
continue;
}
if(a==0&&b==0&c!=0)
{
cout<<"0"<<endl;
continue;
}
if (b==0)
{
ll ans=0;
cout<<"0"<<endl;
continue;
}
printf("%lld\n",bdfc(a,b,-c));
}
return 0;
}
虽然这题卡数据,需要吐槽,但是也学了一些方法
注释中~
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
ll n,x,y;
ll a,b,c,q,p,r,s;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if (b==0) {d=a;x=1;y=0;return;}
exgcd(b,a%b,d,y,x);y-=x*(a/b);
}
ll bdfc(ll a,ll b,ll c)
{
ll d;
exgcd(a,b,d,x,y);
if (c%d) return 0;
x=x*(c/d);
//y=y*(c/d);
int ka=a/d;
int kb=b/d;
if (x>p)
{
int t=(x-p)/kb;//如果要求一个区间的解的数量,首先想要到区间左端之前,但是直接while会被卡TLE,所以,既然只有减法,就可以改成除一下就好
x-=kb*t;//当然要判断一下,最后是否除到下面了,所以再减一下。。
if (x>p) x-=kb;
}
if (b) y=(c-a*x)/b;else y=0;
ll ans=0;
while (x<=q)
{
if (x>=p&&x<=q&&y>=r&&y<=s) ans++;
x+=kb;
y-=ka;
}
return ans;
}
int main()
{
scanf("%lld",&n);
while (n--)
{
scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&p,&q,&r,&s);
if(a==0&&b==0&&c==0)
{
if(q>=p&&s>=r)
cout<<(q-p+1)*(s-r+1)<<endl;
else cout<<"0"<<endl;
continue;
}
if(a==0&&b==0&c!=0)
{
cout<<"0"<<endl;
continue;
}
if (b==0)
{
ll ans=0;
cout<<"0"<<endl;
continue;
}
printf("%lld\n",bdfc(a,b,-c));
}
return 0;
}
相关文章推荐
- CodeVS 1090 [NOIP 2003] 区间DP 解题报告
- 【Codeforces Testing Round 12B】【贪心】Restaurant 选取数量最多的不覆盖区间数
- codevs 1191 数轴染色 区间更新加延迟标记
- CODE[VS] 1080 线段树练习(单值修改、区间求和)
- codevs 1082 一维树状数组区间修改区间查询
- codevs1154 能量项链(区间DP)
- 【日常学习】【区间DP】codevs1048 石子归并题解
- codevs 1299 线段树 区间更新查询
- CODE[VS] 1082 线段树练习 3 (区间修改、区间求和)
- 【区间DP+高精】codevs1166 矩阵取数游戏题解
- 扩展gcd codevs 1213 解的个数
- codevs 1085 数字游戏 (环形区间dp+负数取膜)
- codevs 1966 乘法游戏 区间DP 解题报告
- codevs1040统计单词个数(区间+划分型dp)
- 【NOIP2012】 CODE[VS] 1217 借教室(线段树维护区间最小值)
- Codevs2102[石子归并 2] 区间DP
- codevs 1191 线段树 区间更新(水)
- [CodeVS1081]线段树练习2(区间修改+单点询问)
- Codevs1213 解的个数
- 【codevs1081】【树状数组】区间修改 单点查询