• HDU6274 Master of Sequence(二分+预处理)


    可以把式子进行拆分,拆分完后,我们关注的是两个整除后的关系以及两个余数之间的关系。

    余数只要相减那么答案就是建议,否则答案不变。这是因为两个余数相减,除a[i]是不可能大于1的,但是可以小于0,因为是下取整,所以答案-1.

    因此我们可以分三层维护这个答案。

    现在的关键是如何快速维护这几个答案。因为a[i]只有1000,这告诉我们余数也不会大于1000,所以我们可以开个二维数组去记录每个a[i]对应的所有b[i]产生的答案

    因为询问也不会超过1000,我们发现这个有单调性,可以二分check,复杂度也没问题。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const ll inf=1e15;
    typedef long long ll;
    int n,m;
    ll sum[2020][2020];
    int a[N],b[N];
    ll ans=0;
    bool check(ll x,ll y){
        ll res=0;
        for(int i=1;i<=1000;i++){
            res+=sum[i][0]*(x/i);
            res-=sum[i][x%i+1];
        }
        return res>=y;
    }
    ll solve(ll x){
        ll l=1,r=inf;
        while(l<r){
            ll mid=l+r>>1;
            if(check(mid,x)){
                r=mid;
            }
            else{
                l=mid+1;
            }
        }
        return l;
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            cin>>n>>m;
            int i,j;
            ans=0;
            for(i=1;i<=1000;i++){
                for(j=0;j<=1000;j++)
                    sum[i][j]=0;
            }
            for(i=1;i<=n;i++){
                cin>>a[i];
            }
            for(i=1;i<=n;i++){
                cin>>b[i];
            }
            for(i=1;i<=n;i++){
                sum[a[i]][b[i]%a[i]]++;
                ans+=b[i]/a[i];
            }
            for(i=1;i<=1000;i++){
                for(j=i-1;j>=0;j--){
                    sum[i][j]+=sum[i][j+1];
                }
            }
            while(m--){
                int opt;
                cin>>opt;
                ll x,y;
                if(opt==1){
                    cin>>x>>y;
                    ans-=b[x]/a[x];
                    ans+=b[x]/y;
                    for(i=b[x]%a[x];i>=0;i--){
                        sum[a[x]][i]--;
                    }
                    for(i=b[x]%y;i>=0;i--){
                        sum[y][i]++;
                    }
                    a[x]=y;
                }
                else if(opt==2){
                    cin>>x>>y;
                    ans-=b[x]/a[x];
                    ans+=y/a[x];
                    for(i=b[x]%a[x];i>=0;i--){
                        sum[a[x]][i]--;
                    }
                    for(i=y%a[x];i>=0;i--){
                        sum[a[x]][i]++;
                    }
                    b[x]=y;
                }
                else{
                    cin>>x;
                    cout<<solve(x+ans)<<endl;
                }
            }
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    常用数据库的驱动类/URL/默认端口
    设备驱动程序
    linux内存管理解析1----linux物理,线性内存布局及页表的初始化
    UVA 10564
    ARM GCC CodeSourcery 下载地址
    Linux Shell编程入门
    Flume研究心得
    Bluetooth in Android 4.2 and 4.3(三):Enable Bluetooth
    <机器学习实战>读书笔记--logistic回归
    <机器学习实战>读书笔记--朴素贝叶斯
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13733854.html
Copyright © 2020-2023  润新知