zoukankan      html  css  js  c++  java
  • HDU-6274 Master of Sequence 数学+二分

    HDU-6274 Master of Sequence

    题意

    给出两个长度为(n)的数组(a)(b),设(S(t)=sum_{i=1}^{n} lfloor frac{t-b_i}{a_i} floor)(m)组操作:

    • (1~x~y),将(a[x])改为(y)
    • (2~x~y),将(b[x])改为(y)
    • (3~k),询问 ( ext{min} {t|kle S(t) })

    (nle 10^5,mle 10^4,a_i le 1000,b_i,kle 10^9),第三种操作个数不超过(1000)

    分析

    先把公式拆分一下。

    [S(t)=sum_{i=1}^{n} lfloor frac{t-b_i}{a_i} floor \ =sum_{i=1}^{n} lfloor frac{k1cdot a_i+t\%a_i-k2cdot a_i-b_i\%a_i}{a_i} floor \ =sum_{i=1}^{n} k1-k2-[t\%a_i-b_i\%a_i<0] ]

    由于(a_ile 1000),我们二分(t)的大小,对每种(a_i)用桶分别计算((t\%a_i-b_i\%a_i<0))的个数。

    Code

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=1e5+10;
    typedef long long ll;
    int T,n,m;
    int a[N],b[N];
    int sz[1010];
    int sum[1010][1010];
    inline bool ck(ll x,ll k){
        ll ret=0;
        for(int i=1;i<=1000;++i){
            ret+=x/i*sz[i]-sum[i][x%i+1];
        }
        return ret>=k;
    }
    int main()
    {
        scanf("%d",&T);
        while(T--){
            ll res=0;
            scanf("%d%d",&n,&m);
            memset(sz,0,sizeof sz);
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            for(int i=1;i<=n;i++){
                scanf("%d",&b[i]);
                res+=b[i]/a[i];
                sum[a[i]][b[i]%a[i]]++;
                sz[a[i]]++;
            }
            for(int i=1;i<=1000;i++){
                for(int j=1000;j>=0;j--) sum[i][j]+=sum[i][j+1];
            }
            for(int i=1,op,x,y;i<=m;i++){
                scanf("%d%d",&op,&x);
                if(op==1){
                    scanf("%d",&y);
                    res-=b[x]/a[x];
                    for(int j=0;j<=b[x]%a[x];j++) sum[a[x]][j]--;
                    sz[a[x]]--;
                    a[x]=y;
                    res+=b[x]/a[x];
                    for(int j=0;j<=b[x]%a[x];j++) sum[a[x]][j]++;
                    sz[a[x]]++;
                }else if(op==2){
                    scanf("%d",&y);
                    res-=b[x]/a[x];
                    for(int j=0;j<=b[x]%a[x];j++) sum[a[x]][j]--;
                    sz[a[x]]--;
                    b[x]=y;
                    res+=b[x]/a[x];
                    for(int j=0;j<=b[x]%a[x];j++) sum[a[x]][j]++;
                    sz[a[x]]++;
                }else{
                    ll l=0,r=1e13;
                    while(l<=r){
                        ll mid=l+r>>1;
                        if(ck(mid,x+res)) r=mid-1;
                        else l=mid+1;
                    }
                    printf("%lld
    ",l);
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    【HDOJ】2774 Shuffle
    【POJ】2170 Lattice Animals
    【POJ】1084 Square Destroyer
    【POJ】3523 The Morning after Halloween
    【POJ】3134 Power Calculus
    【Latex】如何在Latex中插入伪代码 —— clrscode3e
    【HDOJ】4801 Pocket Cube 的几种解法和优化
    【HDOJ】4080 Stammering Aliens
    【HDOJ】1800 Flying to the Mars
    SQL语法
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13912298.html
Copyright © 2011-2022 走看看