Codeforces Round #701 (div2)
A. Add and Divide (*1000)
题意
给出两个数\(a,b(1\leq a,b\leq 1e9)\),每次可以进行两种操作之一:
- \(a=\lfloor \frac{a}{b} \rfloor\)
- \(b=b+1\)
计算使得\(a==0\)的最小操作次数
题解
假设最小操作次数需要进行\(x\)次操作1和\(y\)次操作2,显然首先进行\(y\)次操作1会更优。首先计算进行0次操作2(\(b==1\)时先进行1次操作2将\(b\)变成2),再进行若干次操作1将\(a\)变成0的操作次数,之后依次增加操作2的次数,计算此时操作1需要进行的次数,更新总次数的最小值。
由于对于\(b==2\),进行\(\log a\)次操作可以将\(a\)变成0,所以操作2最多进行\(\log a\)次,时间复杂度\(O({\log}^2 a)\)
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
int T;
LL a,b;
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld %lld",&a,&b);
int res=1e9+10;
for(int i=(b==1)?1:0;i<res;i++){
LL a0=a,b0=b+i;
int cnt=i;
while(a0){
a0/=b0;
cnt++;
}
res=min(res,cnt);
}
printf("%d\n",res);
}
}
B. Replace and Keep Sorted (*1200)
题意
给出一列长度为\(n(1\leq n\leq 1e5)\)的严格递增的数列\(a\)和整数\(k(n\leq k\leq 1e9)\),\(1\leq a_i\leq k\),进行\(q(1\leq q\leq 1e5)\)次询问,每次给出一个区间\([l,r]\),计算有多少种长度为\((r-l+1)\)的数列,满足数列只替换了询问区间中某一个位置的数,将它变成\(x\),其中\(1\leq x\leq k\)并且区间依然保持严格单调递增
题解
分类讨论
设当前将询问区间中的某一个数替换成\(x(1\leq x\leq k)\),根据\(x\)的特点判断对答案的贡献:
case 1: \(x<a_l\)。只能将\(a_l\)替换成\(x\),有\(a_l-1\)种满足条件的\(x\)
case 2: \(x>a_r\)。只能将\(a_r\)替换成\(x\),有\(k-a_r\)种满足条件的\(x\)
case 3: \(a_l<x<a_r\)并且\(x\neq a_i(l\leq i\leq r)\)。可以将两个位置替换成\(x\),区间中小于\(x\)的最大值\(b_l\)或者区间中大于\(x\)的最小值\(b_r\),有\((a_r-a_l+1)-(r-l+1)\)种满足条件的\(x\),对答案的贡献为\(2*((a_r-a_l+1)-(r-l+1))\)
case 4: \(x==a_i(l\leq i\leq r)\)。由于数列严格递增,这样的\(x\)无法替换数列中的数,因此对答案的贡献为0
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=100010;
int n,q;
LL k,a[maxn];
int main(){
scanf("%d %d %lld",&n,&q,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
while(q--){
int l,r;
scanf("%d %d",&l,&r);
LL ans=(a[l]-1)+(k-a[r])+2*((a[r]-a[l]+1)-(r-l+1));
printf("%lld\n",ans);
}
}
C. Floor and Mod (*1700)
题意
给出两个整数\(x,y(1\leq x,y\leq 1e9)\),计算有多少个数对\(a,b\)满足\(1\leq a\leq x\),\(1\leq b\leq y\)并且\(\lfloor \frac{a}{b} \rfloor==a\ mod\ b\)
题解
假设\(\lfloor \frac{a}{b} \rfloor==a\ mod\ b==k\),则\(a=kb+k=k(b+1),(b>k)\),所以\(k^2<k(b+1)<a\leq x\),所以\(k\leq \sqrt x)\)。\(k\)的上界为\(\sqrt x\),枚举\(k\),计算对于当前的\(k\),所有\(b\)的可能值,也就确定了每一个\(b\)对应\(a\)的值。根据已知:
得到:
所以对于确定的\(k\),满足条件的\(a,b\)对数为:
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
int T;
LL x,y;
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld %lld",&x,&y);
LL ans=0;
for(LL k=1;k*k<x;k++){
ans+=max(1ll*0,min(y,x/k-1)-k);
}
printf("%lld\n",ans);
}
}
D. Multiples and Power Differences (*2200)
题意
给出一个\(n*m(2\leq n,m\leq 500)\)的矩阵\(a\),\(1\leq a_{ij}\leq 16\),构造一个矩阵\(b\),满足以下条件:
- \(1\leq b_{ij}\leq 1e6\)
- \(b_{ij}\)是\(a_{ij}\)的倍数
- \(b_{ij}\)中相邻元素的差值为\(k^4(k\geq 1)\)
说明:满足条件的构造始终是存在的
题解
仿照西洋棋棋盘的样式建立矩阵\(b\)。\(lcm(1,2,...,16)=720720\),矩阵构造方法为:
case 1: 如果\((i+j)\)是奇(偶)数,则\(b_{ij}=720720\)
case 2: 如果\((i+j)\)是偶(奇)数,则\(b_{ij}=720720+a_{ij}^4\)
#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=510,Lcm=720720;
int n,m,a[maxn][maxn],b[maxn][maxn];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
b[i][j]=Lcm;
if((i+j)&1) b[i][j]+=a[i][j]*a[i][j]*a[i][j]*a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<m;j++){
printf("%d ",b[i][j]);
}
printf("%d\n",b[i][m]);
}
}

浙公网安备 33010602011771号