CF #707 (Div. 2)C、D

https://codeforces.com/contest/1501

C. Going Home
  • 题意:给定一个长度为n的序列,找到一组 x , y , z , w x,y,z,w x,y,z,w,使 a x + a y = a y + a w a_x+a_y=a_y+a_w ax+ay=ay+aw

  • 思路:注意数据范围
    4 ≤ n ≤ 2 e 5 4≤n≤2e5 4n2e5
    1 ≤ a i ≤ 2.5 e 6 1≤a_i≤2.5e6 1ai2.5e6
    因为两个数的和不会超过5e6,所以我们可以枚举所有数对,存下每一个和值所对应的两个数的下标,当某个和值中下标个数大于等于4个,就有解了。(因为每个数只能使用一次,所以只有当两个数下标都没有出现过时,才能存进去)

  • 复杂度分析:不考虑下标重复利用的问题,那么当有4个数对的和相同时,就一定有至少一组解,所以在整体的复杂度不会超过O(3*5e6+1)。(抽屉原理)

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
#define pii pair<int,int>
const int manx = 5e6 + 10;

set<int>fre[manx];
int a[manx/10];
int main()
{
    int n,ans=-1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int temp=a[i]+a[j];
            if(!fre[temp].count(i) && !fre[temp].count(j)){
                fre[temp].insert(i);
                fre[temp].insert(j);
            }
            if((int)fre[temp].size()>=4){
                ans=temp;
                break;
            }
        }
        if(ans!=-1)break;
    }
    if(ans==-1){
        puts("NO");
        return 0;
    }
    puts("YES");
    pii x[4];
    int cou=0;
    for(auto it:fre[ans])x[cou].first=a[it],x[cou++].second=it;
    sort(x,x+4);
    printf("%d %d %d %d\n",x[0].second,x[3].second,x[1].second,x[2].second);
    return 0;
}
D. Two chandeliers
  • 题意:给定两个长度分别为n和m的序列,两个序列循环扩展,问两数组中不相同的第k个数下标为多少。
  • 思路1:对于每一个数,设它在两个数组中相遇的位置为pos,则有:
    p o s ≡ i ( m o d   n ) pos≡i(mod\ n) posi(mod n)
    p o s ≡ j ( m o d   m ) pos≡j(mod\ m) posj(mod m)
    这里就可以用excrt(扩展中国剩余定理)得到pos的最小整数解 p o s ’ pos’ pos
    另外可以注意到,如果pos有解,那么在n和m的一个lcm长度内,存在有且仅有一个解,所以我们就可以算出一个lcm长度内有多少个下标对应的数值是相同的。
    剩下的就可以二分答案了,因为有前面的结论,我们可以直接算出当前二分的数值中每一个lcm所含数值不同的下标个数,不满lcm长度的也可以二分得到数值不同的下标个数。
  • 思路2:因为上面的同余方程只有两个,所以也可以直接合并 i + k 1 ∗ n = j + k 2 ∗ m i+k_1*n=j+k_2*m i+k1n=j+k2m,然后用exgcd求解。
  • 注意:数据范围: 1 ≤ a i , b j ≤ 2 ∗ m a x ( n , m ) 1≤a_i,b_j≤2*max(n,m) 1ai,bj2max(n,m)
  • 方程ax+by = c最小非负整数解的处理
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<bitset>
using namespace std;
//#define int long long
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define mid ((l + r)>>1)
#define chl (root<<1)
#define chr (root<<1|1)
#define lowbit(x) ( x&(-x) )
const int manx = 1e6 + 10;
const int manx2 = 4e7 + 10;
const int INF = 1e9;
const int mod = 244353;

ll n,m,p,gcd;
ll posa[manx],posb[manx],meet[manx];
ll k,cnt=0;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0){
        x=1,y=0;
        return a;
    }
    ll gcd=exgcd(b,a%b,y,x);
    y-=(a/b)*x;
    return gcd;
}
ll query(ll x)
{
    ll ans=x/(n*m/gcd)*cnt;
    ans+=upper_bound(meet+1,meet+cnt+1,x%(n*m/gcd))-meet-1;
    return x-ans;//先算相同的,最后减
}
int main()
{
    memset(posa,0,sizeof posa);
    memset(posb,0,sizeof posb);
    scanf("%lld%lld%lld",&n,&m,&k);
    ll x1,y1;
    gcd=exgcd(n,m,x1,y1);
    for(int i=1;i<=n;i++){
        scanf("%lld",&p);
        posa[p]=i;
    }
    for(int i=1;i<=m;i++){
        scanf("%lld",&p);
        posb[p]=i;
    }
    for(int i=1;i<=2*max(n,m);i++){
        ll x=x1,y=y1,c=posb[i]-posa[i];
        if(!posa[i] || !posb[i] || c%gcd)//若数值a或b中没有这个数,或c不能整除gcd,则无解
            continue;
        x=x*c/gcd;
        x=(x%(m/gcd)+m/gcd)%(m/gcd);
        meet[++cnt]=posa[i]+n*x;
    }//cnt就是每个lcm内相同数值的下标个数
    sort(meet+1,meet+cnt+1);
    ll l=0,r=2e18,ans;
    while(l<=r){
        ll temp=query(mid);
        if(temp==k){
            ans=mid;
            r=mid-1;
        }
        else if(temp<k)l=mid+1;
        else r=mid-1;
    }
    printf("%lld\n",ans);
    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><link rel=icon href=/favicon.ico><link rel=stylesheet type=text/css id=style href=/mob.css><title>泰迪内推</title><link href=/static/css/chunk-213d46f9.6699f04d.css rel=prefetch><link href=/static/css/chunk-27f03f86.a14eed06.css rel=prefetch><link href=/static/css/chunk-3e1db89a.80dc307b.css rel=prefetch><link href=/static/css/chunk-43ac0f34.b39cf2e8.css rel=prefetch><link href=/static/css/chunk-47eb0788.1ef261ba.css rel=prefetch><link href=/static/css/chunk-4df08e90.c15bd54f.css rel=prefetch><link href=/static/css/chunk-604a0331.222a69ed.css rel=prefetch><link href=/static/css/chunk-706e4bb8.ba0c435d.css rel=prefetch><link href=/static/css/chunk-aa019e9e.a24ffcbe.css rel=prefetch><link href=/static/css/chunk-b2d8146e.9f5c8495.css rel=prefetch><link href=/static/js/chunk-0bd9655e.5d19cfbe.js rel=prefetch><link href=/static/js/chunk-213d46f9.5bf0f607.js rel=prefetch><link href=/static/js/chunk-27f03f86.5642dd75.js rel=prefetch><link href=/static/js/chunk-2d0b35ec.0914afe2.js rel=prefetch><link href=/static/js/chunk-2d0dd3b6.0661684c.js rel=prefetch><link href=/static/js/chunk-2d217c6c.0552e504.js rel=prefetch><link href=/static/js/chunk-3e1db89a.32ad918c.js rel=prefetch><link href=/static/js/chunk-43ac0f34.cae47384.js rel=prefetch><link href=/static/js/chunk-47eb0788.f22bea25.js rel=prefetch><link href=/static/js/chunk-4c5e9add.e9181098.js rel=prefetch><link href=/static/js/chunk-4df08e90.a647fb2c.js rel=prefetch><link href=/static/js/chunk-50ab568d.23c2b33f.js rel=prefetch><link href=/static/js/chunk-580d01b5.865ed0ae.js rel=prefetch><link href=/static/js/chunk-604a0331.ff94cd57.js rel=prefetch><link href=/static/js/chunk-706e4bb8.cc1fe1f6.js rel=prefetch><link href=/static/js/chunk-70d08bcf.6283edd1.js rel=prefetch><link href=/static/js/chunk-aa019e9e.a3ad5f18.js rel=prefetch><link href=/static/js/chunk-b2d8146e.cc40e92f.js rel=prefetch><link href=/static/js/chunk-c5bd1154.0a2126f9.js rel=prefetch><link href=/static/js/chunk-f5ae8c94.d4d5a49c.js rel=prefetch><link href=/static/css/chunk-vendors.a57aa87f.css rel=preload as=style><link href=/static/css/frontend.8e826938.css rel=preload as=style><link href=/static/js/chunk-vendors.ce9424b8.js rel=preload as=script><link href=/static/js/frontend.6f4ec638.js rel=preload as=script><link href=/static/css/chunk-vendors.a57aa87f.css rel=stylesheet><link href=/static/css/frontend.8e826938.css rel=stylesheet></head><body><div id=app></div><script src=/static/js/chunk-vendors.ce9424b8.js></script><script src=/static/js/frontend.6f4ec638.js></script></body></html>
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值