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;
    }
    
  • 相关阅读:
    Atitit.执行cli cmd的原理与调试
    Atitit. IE8.0 显示本地图片预览解决方案 img.src=本地图片路径无效的解决方案
    SlidingDrawer的简单实例(抽屉效果)
    Android android.intent.category解析
    layout中加载gif图片
    Java 中 Vector、ArrayList、List 使用深入剖析
    定时器的简单实例
    supportsscreens
    Android屏幕元素层次结构
    panel的抽屉效果
  • 原文地址:https://www.cnblogs.com/xyq0220/p/13912298.html
Copyright © 2011-2022 走看看