codeforces数学1600day6[CodeForces - 1029C多区间交+枚举,CodeForces 992C[数学公式推导],CodeForces 992B[质因数分解+暴力枚举]]

A - Maximal Intersection CodeForces - 1029C


题目大意:就是给你n个区间,这n个区间有公共的区间长度为x,现在叫你从这n个区间中删掉一个使得x最大化。


解题思路:1.所有线段的公共交点就是这些线段里左端的最大值和右端点的最小值构成的区间长度
2.所以我们只要枚举删除每一个线段就可以了

#include <iostream>
#include <cstdio>
#include <stack>
#include <sstream>
#include <vector>
#include <map>
#include <cstring>
#include <deque>
#include <cmath>
#include <iomanip>
#include <queue>
#include <algorithm>
#include <set>
#define mid ((l + r) >> 1) 
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define f first
#define s second
using namespace std;
const int N = 3e5 + 10, eps = 1e-10;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;

PII p[N]; 
int x[N], y[N];
int main()
{
    int  T;
    cin >> T;
    _for(i,0,T) 
    {
        int l ,r;
        cin >> l >> r;
        p[i] = {l,r};
        x[i] = l, y[i] = r;
    }
    sort(x,x+T);
    sort(y,y+T);
    int res = 0;
    _for(i,0,T)
    {
        int l, r;
        if(p[i].f != x[T - 1]) l = x[T - 1];
        else l = x[T - 2];
        
        if(p[i].s != y[0]) r = y[0];
        else r = y[1];
        
        res = max(res,r - l);
    }
    cout << res << endl;
    return 0;
}


B - Nastya and a Wardrobe CodeForces - 992C


题目大意:
你开始有X个裙子 你有K+1次增长机会 前K次会100%的增长一倍 但是增长后有50%的机会会减少一个
给你X,K(0<=X,K<=1e18), 问你最后裙子数量的期望值是多少(答案 mod 1e9+7)


解题思路:推公式其实公式很好推的,按照题目意思模拟一下就可一了 a n s = 2 k + 1 ∗ x − 2 k + 1 ans = 2^{k+1}*x-2^k+1 ans=2k+1x2k+1

#include <iostream>
#include <cstdio>
#include <stack>
#include <sstream>
#include <vector>
#include <map>
#include <cstring>
#include <deque>
#include <cmath>
#include <iomanip>
#include <queue>
#include <algorithm>
#include <set>
#define mid ((l + r) >> 1) 
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define f first
#define s second
using namespace std;
const int N = 3e5 + 10, mod = 1e9 + 7;
const double eps = 1e-10;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;

LL x, k;
LL qmi(LL a, LL b)
{
    LL res = 1;
    while(b)
    {
        if(b & 1) res = (res * a) % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res % mod;
}


int main()
{
    cin >> x >> k;
    if(k == 0) cout << (x * 2) % mod << endl;
    else if(x == 0) cout << "0" << endl;
    else
    {
        LL ans = ((qmi(2,k+1) * (x % mod))%mod - qmi(2,k) + 1 + mod ) % mod;
        cout << ans << endl;
    }
    return 0;
}
/*
1 411
485514976
*/


C - Nastya Studies Informatics CodeForces - 992B


题目大意:给你一个区间 [ l , r ] [l,r] [l,r],问你这里面有多少对数的 a , b , G C D ( a , b ) = = x , L C M ( a , b ) = = y a,b,GCD(a,b)==x,LCM(a,b)==y a,b,GCD(a,b)==x,LCM(a,b)==y


解题思路:1.这是我开始想法根据定义: G C D ( a , b ) = p 1 m i n ( a , b ) ∗ p 2 m i n ( a , b ) . . . . . . p n m i n ( a , b ) = x GCD(a,b)=p_1^{min(a,b)}*p_2^{min(a,b)}......p_n^{min(a,b)}=x GCD(a,b)=p1min(a,b)p2min(a,b)......pnmin(a,b)=x
L C M ( a , b ) = p 1 m a x ( a , b ) ∗ p 2 m a x ( a , b ) . . . . . . ∗ p n m a x ( a , b ) = y LCM(a,b) = p_1^{max(a,b)}*p_2^{max(a,b)}......*p_n^{max(a,b)}=y LCM(a,b)=p1max(a,b)p2max(a,b)......pnmax(a,b)=y那么 a a a b b b就是在这些因子中每个对应位挑选一个 p x m i n ( a , b ) 或 者 是 p x m a x ( a , b ) x ∈ [ 1 , n ] p_x^{min(a,b)}或者是p_x^{max(a,b)}x\in[1,n] pxmin(a,b)pxmax(a,b)x[1,n]再乘起来组合成的
2.那么我们就可以将 x , y x,y x,y分解质因数对于每个对应位置用dfs去枚举一共有 2 n 2^n 2n情况
3.我们可以证明n是不大过10的因为前10个质因子相乘已经大过 1 e 9 1e9 1e9
4.我们还要特判一下 y y y是否是 x x x的倍数


#include <iostream>
#include <cstdio>
#include <stack>
#include <sstream>
#include <vector>
#include <map>
#include <cstring>
#include <deque>
#include <cmath>
#include <iomanip>
#include <queue>
#include <algorithm>
#include <set>
#define mid ((l + r) >> 1) 
#define Lson rt << 1, l , mid
#define Rson rt << 1|1, mid + 1, r
#define ms(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define _for(i,a,b) for( int i = (a); i < (b); ++i)
#define _rep(i,a,b) for( int i = (a); i <= (b); ++i)
#define for_(i,a,b) for( int i = (a); i >= (b); -- i)
#define rep_(i,a,b) for( int i = (a); i > (b); -- i)
#define lowbit(x) ((-x) & x)
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define INF 0x3f3f3f3f
#define hash Hash
#define next Next
#define f first
#define s second
using namespace std;
const int N = 2e5 + 10, eps = 1e-10;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
map<LL,int> factor[2];
map<PII,bool> res;
LL poi, f[N];
LL l, r, x, y;
LL qmi(LL a, LL b)
{
    LL res = 1;
    while(b)
    {
        if(b & 1) res = (res * a);
        b >>= 1;
        a = a * a;
    }
    return res;
}
void Factor(LL x, int t)
{
     for(LL i = 2; i * i <= x; ++ i)
    {
        if(x % i == 0)
        {
            int b = 0;
            while(x % i == 0)
            {
                x /= i;
                b ++;
            }
            factor[t][i] = b;
        }
    }
    if(x != 1) factor[t][x] = 1;
}

inline void dfs(int deep, LL mul)
{
    if(deep == poi) 
    {
        if(mul >= l && mul <= r && x * y / mul >= l && x * y / mul <= r)
          res[{mul,x*y/mul}] = true;
        return;
    }
    dfs(deep+1,mul * qmi(f[deep],factor[0][f[deep]]));
    dfs(deep+1,mul * qmi(f[deep],factor[1][f[deep]]));
    return;
}

int main()
{
   
    cin >> l >> r >> x >> y; 
    Factor(x,0);
    Factor(y,1);
    if(y % x != 0) 
    {
        cout << "0";
        return 0;
    }
    for(auto it : factor[1])
       f[poi++] = it.f;
     dfs(0,1);
     cout << res.size() << endl;
    return 0;
}

解法2:因为 a a a b b b一定是 L C M ( a , b ) LCM(a,b) LCM(a,b)的因子,那么我们可以暴力枚举 L C M ( a , b ) LCM(a,b) LCM(a,b)所有的因子去判断一下就可以了(下面是别人的代码)


#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+50;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
typedef long long ll;
ll l,r,x,y;
ll ans=0;
void check(ll a)
{
    ll b = x*y/a;
    //cout<<a<<" "<<b<<endl;
    if(a<l||a>r)return;
    if(b<l||b>r)return;
    if(__gcd(a,b)!=x)return;
   // cout<<a<<" "<<b<<endl;
    ans+=1;
}
int main()
{
    scanf("%I64d%I64d%I64d%I64d",&l,&r,&x,&y);
    for(ll i=1;i*i<=y;i++)
    {
        if(y%i==0)
        {
            ll p = y / i;

            check(i);
            if(p!=i)
            {
                check(p);
            }
        }
    }
    //if(x==y) check(y);
    printf("%I64d\n",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值