题解:CF2006D Iris and Adjacent Products
相关人员:验题人
先考虑对于一次询问如何做。根据数论分块知识可以知道本质不同的数的种类是
考虑模拟构造过程。倒数第
对于每次询问,只需要计算出每类数各有几个即可。
考虑到直接用前缀和计算答案也许会 MLE,故以大小为
时间复杂度
验题代码:
#include<bits/stdc++.h>
using namespace std;
namespace _wrk{;
#define int long long
int b[100005];
const int B=32;
signed p[101005/B][2503];
int re[2503];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
int n,q,R;
cin>>n>>q>>R;
for(int i=1;i<=n;i++){
cin>>b[i];
}
vector<int>u;
for(int l=1;l<=R;l=(R/(R/l))+1){
u.push_back(l);
}
for(int i=B;i<=n;i+=B){
int h=i/B;
for(int j=1;j<=u.size();j++){
p[h][j]=p[h-1][j];
}
for(int w=i-B+1;w<=i;w++){
p[h][upper_bound(u.begin(),u.end(),b[w])-u.begin()]++;
}
}
while(q--){
int l,r;
cin>>l>>r;
for(int i=1;i<=u.size();i++)re[i]=0;
for(;l%B!=1&&l<=r;l++){
re[upper_bound(u.begin(),u.end(),b[l])-u.begin()]++;
}
for(;r%B&&l<=r;r--){
re[upper_bound(u.begin(),u.end(),b[r])-u.begin()]++;
}
if(l<=r)for(int i=1;i<=u.size();i++){
re[i]+=p[r/B][i]-p[(l-1)/B][i];
}
int a=0,ans=0;
int h=0;
int ll=1,rr=u.size();
while(ll<rr){
a+=re[ll];
if((re[rr]||re[ll])){
if(h){
ans++;a++;h=0;
}
int w=re[rr];
int c=min(a,w);
a-=c;w-=c;
int p=w/2;
ans+=p;
h=w-p*2;
}
ll++;rr--;
}
if(ll==rr){
if(re[ll]&&h) ans++;
}
cout<<ans<<' ';
}
cout<<'\n';
}
return 0;
}
}
signed main(){
return _wrk::main();
}
(注:本题原来空间限制 128MB,之后出题人看到我的代码想搞成32MB,但是上面的