Master of Sequence

Master of Sequence

时间限制: 10 Sec  内存限制: 128 MB

题目描述

There are two sequences a1,a2,...,an , b1,b2,...,bn . Let  . There are m operations within three kinds as following:
• 1 x y: change value ax to y.
• 2 x y: change value bx to y.
• 3 k: ask min{t|k≤S(t)}

输入

The first line contains a integer T (1≤T≤5) representing the number of test cases.
For each test case, the first line contains two integers n (1≤n≤100000), m (1≤m≤10000).
The following line contains n integers representing the sequence a1,a2,...,an .
The following line contains n integers representing the sequence b1,b2,...,bn .
The following m lines, each line contains two or three integers representing an operation mentioned above.
It is guaranteed that, at any time, we have 1≤ai≤1000, 1≤bi,k≤109 . And the number of queries (type 3 operation) in each test case will not exceed 1000.

输出

For each query operation (type 3 operation), print the answer in one line.

样例输入

2
4 6
2 4 6 8
1 3 5 7
1 2 3
2 3 3
3 15
1 3 8
3 90
3 66
8 5
2 4 8 3 1 3 6 24
2 2 39 28 85 25 98 35
3 67
3 28
3 73
3 724
3 7775

样例输出

17
87
65
72
58
74
310
2875

题目链接:http://icpc.upc.edu.cn/problem.php?cid=1723&pid=10

思路: (t-bi)/ai = [k1*ai+c1-(k2*ai+c2)]/ai = k1-k2 + (c1-c2)/ai,这样就可以分别维护k1的和,k2的和,再维护一下c2>c1的情况。
#include<bits/stdc++.h>
#define N 1005
using namespace std;

long long c[N][N]={0};

void updata(long long arr[],long long pos,long long value)
{
    pos++;
    for(long long i=pos;i<N;i+=i&(-i))arr[i]+=value;
}

long long Sum(long long arr[],long long pos)
{
    pos++;
    long long ans=0;
    for(long long i=pos;i>0;i-=i&(-i))ans+=arr[i];
    return ans;
}

long long sum_a[N]={0};
long long cnt=0;


void init()
{
    cnt=0;
    memset(sum_a,0,sizeof(sum_a));
    memset(c,0,sizeof(c));
}

long long a[N*100],b[N*100];

long long f(long long t)
{
    long long ans=cnt;
    for(long long i=1;i<N;i++)
    if(sum_a[i])
    {
        ans+=t/i*sum_a[i];
        ans-=sum_a[i]-Sum(c[i],t%i);
    }
    return ans;
}


int  main()
{
    long long t;
    scanf("%lld",&t);
    while(t--)
    {
        init();
        long long n,m;
        scanf("%lld %lld",&n,&m);
        for(long long i=1;i<=n;i++)scanf("%lld",&a[i]);
        for(long long i=1;i<=n;i++)scanf("%lld",&b[i]);
        
        for(long long i=1;i<=n;i++)
        {
            sum_a[a[i]]++;
            updata(c[a[i]],b[i]%a[i],1);
            cnt-=b[i]/a[i];
        }
        
        while(m--)
        {
            long long type;
            scanf("%lld",&type);
            if(type==1)
            {
                long long x,y;
                scanf("%lld %lld",&x,&y);
                sum_a[a[x]]--;
                updata(c[a[x]],b[x]%a[x],-1);
                cnt+=b[x]/a[x];
                
                sum_a[y]++;
                updata(c[y],b[x]%y,1);
                cnt-=b[x]/y;
                a[x]=y;
            }
            else
            if(type==2)
            {
                long long x,y;
                scanf("%lld %lld",&x,&y);
                updata(c[a[x]],b[x]%a[x],-1);
                cnt+=b[x]/a[x];
                
                updata(c[a[x]],y%a[x],1);
                cnt-=y/a[x];
                b[x]=y;
            }
            else
            {
                long long k;
                scanf("%lld",&k);
                long long l=0,r=1e14;
                long long ans=0;
                
                while(l<=r)
                {
                    long long mid=(l+r)/2;
                    if(f(mid)>=k)
                    {
                        ans=mid;
                        r=mid-1;
                    }
                    else
                    l=mid+1;
                }
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/tian-luo/p/10660118.html