社区讨论
WA+T求调
P13984数列分块入门 9参与者 2已保存回复 18
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @mjthkdu9
- 此快照首次捕获于
- 2025/12/31 11:58 2 个月前
- 此快照最后确认于
- 2026/01/02 21:35 2 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
int n;
const int N = 3e5 + 5;
const int sqr = 800;
int f[sqr][N];//f[i][j]表示前i个块中j出现的次数
int g[sqr][sqr];//g[i][j]表示第i到j块中最小的众数
int a[N];
int cl[N],cr[N],tag[N];
vector<int> tmp;
map<int,int> mp;
int idx;
int nums[N];
inline void init(){
int B = sqrt(n);
int len = (n%B == 0 ? n/B : n/B+1);
for(int i = 1;i <= len;i ++){//get G
memset(nums,0,sizeof(nums));
pair<int,int> maxx = {INT_MIN,0};
for(int j = i;j <= len;j ++){
for(int k = (j - 1) * B + 1;k <= min(n,j*B);k ++){
nums[a[k]] ++;
if(nums[a[k]]>maxx.first){
maxx = {nums[a[k]],a[k]};
}
else if(nums[a[k]] == maxx.first) maxx.second = min(maxx.second,a[k]);
}
g[i][j] = maxx.second;
}
}
for(int i = 1;i <= len;i ++){//get F
memset(nums,0,sizeof(nums));
for(int j = (i - 1)*B + 1;j <= min(i*B,n);j ++){
nums[a[i]] ++;
}
for(int j = (i - 1)*B + 1;j <= min(i*B,n);j ++){
f[i][a[j]] = f[i-1][a[j]] + nums[a[j]];
}
}
for(int i = 1;i <= len;i ++){
for(int j = (i - 1)*B + 1;j <= min(i*B,n);j ++){
cl[j] = (i - 1)*B + 1;
cr[j] = min(i*B,n);
tag[j] = i;
}
}
}
inline int query(int l,int r){
if(tag[r]-tag[l]+1 <= 2){
memset(nums,0,sizeof(nums));
pair<int,int> maxx = {INT_MIN,0};
for(int i = l;i <= r;i ++){
nums[a[i]] ++ ;
if(nums[a[i]] > maxx.first) maxx = {nums[a[i]],a[i]};
else if(nums[a[i]] == maxx.first) maxx.second = min(maxx.second,a[i]);
}
return tmp[maxx.second - 1];
}
else{
pair<int,int> maxx = {f[tag[r] - 1][g[tag[l] + 1][tag[r] - 1]] - f[tag[l]][g[tag[l] + 1][tag[r] - 1]],g[tag[l] + 1][tag[r] - 1]};
memset(nums,0,sizeof(nums));
// nums[g[tag[l] + 1][tag[r] - 1]] = f[r - 1][g[tag[l] + 1][tag[r] - 1]] - f[l][g[tag[l] + 1][tag[r] - 1]];
for(int i = l;i <= cr[l];i ++){
nums[a[i]] ++ ;
if(nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]] > maxx.first) maxx = {nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]],a[i]};
else if(nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]] == maxx.first) maxx.second = min(maxx.second,a[i]);
}
for(int i = cl[r];i <= r;i ++){
nums[a[i]] ++ ;
if(nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]] > maxx.first) maxx = {nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]],a[i]};
else if(nums[a[i]] + f[tag[r] - 1][a[i]]-f[tag[l]][a[i]] == maxx.first) maxx.second = min(maxx.second,a[i]);
}
return tmp[maxx.second - 1];
}
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n;
for(int i = 1;i <= n;i ++){
cin >> a[i];
tmp.push_back(a[i]);
}
sort(tmp.begin(),tmp.end());
tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());
for(auto v:tmp){
mp[v] = ++idx;//返回的话就是tmp[a[i] - 1]
}
for(int i = 1;i <= n;i ++){
a[i] = mp[a[i]];
}
init();
for(int i = 1;i <= n;i ++){
int l,r;
cin >> l >> r;
cout << query(l,r) << "\n";
}
return 0;
}
回复
共 18 条回复,欢迎继续交流。
正在加载回复...