• CodeForces 1389E Calendar Ambiguity 题解


    CF1389E链接

    首先你得看懂题目以及它给你的图。“‘第 (x) 个月的第 (y) 天’ 与 ‘第 (y) 个月的第 (x) 天’ 在它的那周的同一天“怎么理解?

    ”第 (x) 个月的第 (y) 天“ 转换为 “总共第 ((x-1)d + y) 天”,“第 (y) 个月的第 (x) 天“ 转换为 “总共第 ((y-1)d + x) 天”。

    同时,可以发现“在它的那周 的同一天”时,两个天数是模 (w) 同余的。

    也就是说,当 (1 leq x,y leq min(m,d)) 时,

    [(x-1)d + y equiv (y-1)d + x pmod w ]

    注意到 ((x-1)d) 实质上是 (dx - d)((y-1)d) 实质上是 (dy - d) ,约去 (-d) ,可得

    [dx + y equiv dy + x pmod w ]

    移项,得

    [dx - x equiv dy - y pmod w ]

    [(d-1)x equiv (d-1)y pmod w ]

    (d-1)(w) 可能不是互质的。考虑令它们互质,把它们除以 (gcd(d-1,w)),得到新的 (D)(w')(D = frac{d-1}{gcd(d-1,w)}),(w' = frac{w}{gcd(d-1,w)})),这样就可以保证 (x < w') 时,(Dx mod w') 互不相同。这样就可以光明正大地消去 (D) 了。

    [x equiv y pmod {w'} ]

    (min(m,d))(d) 是原先的,不是大写) 为 (lim)。如果 (lim) 比较小,可以直接枚举余数 (r) ,计算出 ([1,lim]) 中满足 (k mod w')(k) 的数量 (num),它的贡献为 (frac{num(num-1)}{2})。这里 (lim) 可能很大,换个做法,我们发现 (num) 的取值只有两种情况。

    (num = lfloor frac{lim}{w'} floor) ,有 ((w' - (lim mod w'))) 组;

    (num = lfloor frac{lim}{w'} floor + 1) ,有 ((lim mod w')) 组。

    两种累加起来就好了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mit map<int,int>::iterator
    #define sit set<int>::iterator
    #define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
    #define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
    #define ltype int
    #define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
    #define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
    #define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mpr make_pair
    #define pb push_back
    #define fastio ios::sync_with_stdio(false)
    const int inf=0x3f3f3f3f,mod=1000000007;
    const double pi=3.1415926535897932,eps=1e-6;
    void chmax(int &x,int y){if(x < y) x = y;}
    void chmin(int &x,int y){if(x > y) x = y;}
    int T,m,d,w;
    int gcd(int x,int y){
        if(!y) return x;
        return gcd(y, x%y);
    }
    ll f(ll x){
        return x * (x-1) / 2;
    }
    int main()
    {
        fastio;
        cin>>T;
        while(T--) {
            cin>>m>>d>>w;
            int k = gcd(d - 1, w);
            int w1 = w / k, lim = min(d, m);
            ll A = ll(lim % w1) * f(lim / w1 + 1), B = ll(w1 - lim % w1) * f(lim / w1);
            cout<<A+B<<'
    ';
        }
        return 0;
    }
    
  • 相关阅读:
    Defcon 23最新开源工具NetRipper代码分析与利用
    如何确定恶意软件是否在自己的电脑中执行过?
    Meteor ToDo App实例
    Meteor在手机上运行
    Meteor部
    Meteor结构
    Meteor package.js
    Meteor Assets资源
    Meteor计时器
    C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
  • 原文地址:https://www.cnblogs.com/yz-beacon-cwk/p/13410729.html
Copyright © 2020-2023  润新知