B题
- 题意
- 思路
前缀和处理区间,端点处特殊判断 - 代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int a[N];
int b[N];
void solve()
{
int n,q,k;
cin>>n>>q>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
b[1]=(a[2]-1);
for(int i=2;i<n;i++)
{
b[i]=a[i+1]-a[i-1]-2;
b[i]+=b[i-1];
}
while(q--)
{
int l,r;
cin>>l>>r;
if(r-l==1)
{
ll res=(k-a[l]-1);
res+=a[r]-2;
cout<<res<<endl;
continue;
}
if(l==r)
{
cout<<k-1<<endl;
continue;
}
ll res=b[r-1]-b[l];
res+=(k-a[r-1]-1);
res+=a[l+1]-2;
cout<<res<<endl;
}
}
int main()
{
int t;
t=1;
while(t--)
solve();
}
C题
- 题意
- 思路
哎,只想到了能够
O
(
1
)
O(1)
O(1)时间内枚举
k
k
k,但是没想到k的范围是在
x
\sqrt{x}
x
内的。哎。 - 代码(自己敲得哦)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
void solve()
{
int x,y;
cin>>x>>y;
ll res=0;
res=1ll*min(y-1,x-2);
res=max(1ll*0,res);
for(int i=2;i*i<=x;i++)
{
ll m=x/i;
m-=(i+1);
m=max(1ll*0,m);
ll n=y-i;
n=max(0*1ll,n);
res+=1ll*min(n,m);
}
cout<<res<<endl;
}
int main()
{
int t;
cin>>t;
while(t--)
solve();
}