JZOJ 5439. 【NOIP2017提高A组集训10.31】Calculate

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangjingyuan107/article/details/78408569

题目

在这里插入图片描述
数据范围
在这里插入图片描述

题解

直接求每个 T B [ i ] A [ i ] \lfloor\frac{T-B[i]}{A[i]}\rfloor 不是很容易。
突破口:① A i A_i 的范围很小。考虑将 A i A_i 相同的归为一类。
②此题具有二分性质。随着T增大, S ( T ) S(T) 不会减小。可以二分。
③带下取整符号的式子不好直接快速求值,尝试将下取整符号删除。
问题转化成求 S ( T ) S(T)
考虑将 A i A_i 相同的归为一类,相当于固定住了 A i A_i
设n对数 ( A i , B i ) (A_i,B_i) 中, A a 1 = A a 2 = A a 3 = . . . = A a k = x A_{a1}=A_{a2}=A_{a3}=...=A_{ak}=x
那么x对 S ( T ) S(T) 的贡献为:
i = 1 k T B a i x = i = 1 k ( T x B a i x ) ( B a i T ) % x x \sum_{i=1}^k\lfloor\frac{T-B_{ai}}{x}\rfloor=\sum_{i=1}^k(\frac{T}{x}-\frac{B_{ai}}{x})-\lfloor\frac{(B_{ai}-T)\%x}{x}\rfloor
随着 B a i B_{ai} 的增大, B a i T B_{ai}\geq T a i a_i 的数量也会不减少。
然而修改操作让我们不能直接对这么多个 ( A i , B i ) (A_i,B_i) 中相同 A i A_i 的数对,按照 B i B_i 从小到大排序。
A i < = 1000 A_i<=1000 ?不需要按照 B i B_i 排序,直接存个和模 A i A_i 有关的前缀和就好了。
假设 B a 1 , B a 2 , . . . , B a k B_{a1},B_{a2},...,B_{ak} 中,有p个 T % x \geq T\%x
则x对 S ( T ) S(T) 的贡献为:
i = 1 k ( T x B a i x ) q \sum_{i=1}^k(\frac{T}{x}-\frac{B_{ai}}{x})-q

心得

①范围小的,可尝试分分类。
②带下取整符号的式子不好直接快速求值,尝试将下取整符号删除。
③如果花费不多的时间预处理一种信息,同时可以用很小的时间复杂度去维护预处理的信息,那么可以考虑预处理这一种信息。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100010
#define M 1010
#define LL long long
#define P(a) putchar(a) 
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
	LL op,x,y,id;
};note qu[N];
LL i,j,k,l,r,n,m,S,T;
LL op,x,y,delta;
LL L,R,mid,ans,last,temp,mx;
LL a[N],b[N];
LL a1[M][M];
LL cz[M][2];
bool pp;
LL read(){
	LL res=0,fh=1;char ch;
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')fh=-1,ch=getchar();
	while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
	return res*fh;
}
void write(LL x){
	if(x>9)write(x/10);
	P(x%10+'0');
}
bool cmp(note x,note y){return x.x<y.x;}
int main(){
	T=read();
	while(T--){
		memset(a1,0,sizeof(a1));
		memset(cz,0,sizeof(cz));
		n=read();m=read();
		fo(i,1,n)a[i]=read();
		mx=0;
		fo(i,1,n){
			b[i]=read();
			cz[a[i]][0]+=b[i]/a[i];
			cz[a[i]][1]++;
			mx=max(mx,a[i]);
			temp=b[i]%a[i];
			a1[a[i]][temp]++;
		}
		fo(i,1,mx)fo(j,1,i)a1[i][j]+=a1[i][j-1];
		fo(i,1,m){
			qu[i].op=read();
			if(qu[i].op<3){
				qu[i].x=read(),qu[i].y=read();
			} else qu[i].x=read();
			qu[i].id=i;
		}
		fo(i,1,m){
			if(qu[i].op==3){
				L=0,ans=R=1000000000000;
				while(L<R){
					mid=(L+R)>>1;
					S=0;
					fo(j,1,mx)S+=cz[j][1]*(mid/j)-cz[j][0]-a1[j][j]+a1[j][mid%j];
					if(S>=qu[i].x)ans=R=mid;else L=mid+1;
				}
				write(ans),P('\n');
			} else
			if(qu[i].op==1){
				x=qu[i].x,y=qu[i].y;
				cz[a[x]][0]-=b[x]/a[x];cz[a[x]][1]--;
				fo(j,b[x]%a[x],a[x])a1[a[x]][j]--;
				a[x]=y;mx=max(mx,y);
				cz[a[x]][0]+=b[x]/a[x];cz[a[x]][1]++;
				fo(j,b[x]%a[x],a[x])a1[a[x]][j]++;
			} else{
				x=qu[i].x,y=qu[i].y;
				cz[a[x]][0]+=y/a[x]-b[x]/a[x];
				l=b[x]%a[x],r=y%a[x],delta=-1;
				if(l>r)swap(l,r),delta=1;
				fo(j,l,r-1)a1[a[x]][j]+=delta;
				b[x]=y;
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/huangjingyuan107/article/details/78408569