zoukankan      html  css  js  c++  java
  • D. Concatenated Multiples 解析(思維)

    Codeforce 1029 D. Concatenated Multiples 解析(思維)

    今天我們來看看CF1029D
    題目連結

    題目
    給你一個序列(a)和一個數字(k),求有幾種indices pair可以讓兩個數字串接在一起之後可以被(k)整除。

    前言

    set,map這些東西的常數真的有夠高阿

    想法

    (a_i)(a_j)串接起來是(a_i imes 10^{digit(a_j)}+a_j),我們固定一個(a_i)(digit(???)),要看看哪些(a_j)符合長度是(digit(???))和串接起來可被整除。

    實作細節:我們可以先把相同長度的(a_j)放到一個(vector)裡,並且接著(a_j\%=k)
    如此一來決定了(a_i imes 10^{digit(???)}mod k)是多少以後,只需要找到在同樣長度的(a_j)中,哪些剛好(=(k-(a_i imes 10^{digit(???)}mod k))mod k),而又因為我們已經把(a_j\%=k)過了,所以可以在(sort)過同樣長度的(a_j)後,直接(upperbound-lowerbound)找同樣值的元素有多少個。
    還有,(digit(a_j))的其中一種求法是(digit(a_j)=1+log10(a_j))

    其實我一開始是用(map)實作的,想法是固定(a_j)然後看看(map)裡又多少個(a_i imes 10^{digit(???)})剛好可以符合要求,然後從前往後+從後往前各看一次。然而這題的(kle1e9),因此(map)非常可能需要(insert)非常多空白元素,造成TLE,其中一部分造成TLE的原因是因為(insert)時要(allocate)新記憶體位置,這樣造成非常大的常數。

    程式碼(正常作法):

    const int _n=2e5+10;
    int t,n,k,a[_n],dig[_n],ten[11];
    VI d2a[_n];
    ll ans;
    main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
      cin>>n>>k;rep(i,0,n)cin>>a[i];ten[0]=1;rep(i,1,11)ten[i]=1ll*ten[i-1]*10%k;
      rep(i,0,n)dig[i]=1+log10(a[i]),a[i]%=k,d2a[dig[i]].pb(a[i]);
      rep(i,1,11)sort(all(d2a[i]));
      rep(i,0,n)rep(j,1,11){
        t=k-1ll*a[i]*ten[j]%k;if(t==k)t=0;
        ans+=upper_bound(all(d2a[j]),t)-lower_bound(all(d2a[j]),t);
        if(dig[i]==j and a[i]==t)ans--;
      }cout<<ans<<'
    ';
      return 0;
    }
    

    標頭、模板請點Submission看
    Submission

    程式碼(改成unordered_map以後1800ms的AC):

    const int _n=2e5+10;
    int t,n,k,a[_n];
    ll ans;
    ll ten[11]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000ll};
    struct pair_hash
    {
    	template <class T1, class T2>
    	std::size_t operator() (const std::pair<T1, T2> &pair) const
    	{
    		return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
    	}
    };
    unordered_map<PII,int,pair_hash> mp;
    main(void) {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
      cin>>n>>k;rep(i,0,n)cin>>a[i];
      rep(i,0,n){
        ans+=mp[{(k-a[i]%k)%k,1+log10(a[i])}];
        rep(j,1,11)mp[{(1ull*a[i]*ten[j])%(1ull*k),j}]++;
      }mp.clear();
      per(i,0,n){
        ans+=mp[{(k-a[i]%k)%k,1+log10(a[i])}];
        rep(j,1,11)mp[{(1ull*a[i]*ten[j])%(1ull*k),j}]++;
      }cout<<ans<<'
    ';
      return 0;
    }
    

    標頭、模板請點Submission看
    Submission

  • 相关阅读:
    解释器
    桥接
    组合
    hbase读性能优化
    Hbase为什么写比读快
    http和https区别
    R apply() 函数和 tapply() 函数
    R 语言 decostand() 函数
    R多行交叉作图
    k-mean 拐点
  • 原文地址:https://www.cnblogs.com/petjelinux/p/13620450.html
Copyright © 2011-2022 走看看