3 条题解
-
0
#include<bits/stdc++.h> using namespace std; #define int long long const int N=1e5+10,M=400; int s[M][N],p[M][M],a[N],b[N],c[N],n,B,len,blen; void init() { for(int i=1;i<=len;i++) { for(int j=1;j<=blen;j++)c[j]=0; int mx=-1e9,id=1e9; for(int j=i;j<=len;j++) { for(int k=(j-1)*B+1;k<=min(j*B,n);k++) { c[a[k]]++; if(c[a[k]]>mx) mx=c[a[k]],id=a[k]; else if(c[a[k]]==mx)id=min(id,a[k]); } p[i][j]=id; } } for(int i=1;i<=len;i++) { for(int j=1;j<=blen;j++)s[i][j]=s[i-1][j]; for(int j=(i-1)*B+1;j<=min(i*B,n);j++)s[i][a[j]]++; } } int query(int l,int r) { int bl=(l-1)/B+1,br=(r-1)/B+1; if(br-bl<=1) { for(int i=l;i<=r;i++)c[a[i]]=0; int mx=-1e9,id=1e9; for(int i=l;i<=r;i++) { c[a[i]]++; if(c[a[i]]>mx)mx=c[a[i]],id=a[i]; else if(c[a[i]]==mx)id=min(id,a[i]); } return b[id]; } else { for(int i=l;i<=bl*B;i++)c[a[i]]=s[br-1][a[i]]-s[bl][a[i]]; for(int i=(br-1)*B+1;i<=r;i++)c[a[i]]=s[br-1][a[i]]-s[bl][a[i]]; int id=p[bl+1][br-1],mx=s[br-1][id]-s[bl][id];c[id]=mx; for(int i=l;i<=bl*B;i++) { c[a[i]]++; if(c[a[i]]>mx)mx=c[a[i]],id=a[i]; else if(c[a[i]]==mx)id=min(id,a[i]); } for(int i=(br-1)*B+1;i<=r;i++) { c[a[i]]++; if(c[a[i]]>mx)mx=c[a[i]],id=a[i]; else if(c[a[i]]==mx)id=min(id,a[i]); } return b[id]; } } signed main() { cin>>n;B=sqrt(n);len=(n-1)/B+1; for(int i=1;i<=n;i++)cin>>a[i],b[i]=a[i]; sort(b+1,b+n+1);blen=unique(b+1,b+n+1)-b-1; for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+blen+1,a[i])-b; init(); for(int i=1;i<=n;i++) { int l,r;cin>>l>>r; cout<<query(l,r)<<'\n'; } return 0; } -
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e5 + 10, sqrtN = 350; // 区间查询众数 // a[i]记录离散化后的值,b[i]记录每个点i所在块; // f[i][j]记录从第i块到第j块的众数 // pos[i]记录离散化后值为i的所有位置,用于二分查询出现次数 // 每个块i的左端点L[i]、右端点R[i] int n, a[N], b[N], L[sqrtN], R[sqrtN], f[sqrtN][sqrtN]; vector<int> vals, pos[N]; int tmp_cnt[N], vis[N], timer = 0; int vis2[N], timer2 = 0; signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; vals.push_back(a[i]); } // 离散化 sort(vals.begin(), vals.end()); vals.erase(unique(vals.begin(), vals.end()), vals.end()); for (int i = 1; i <= n; i++) { a[i] = lower_bound(vals.begin(), vals.end(), a[i]) - vals.begin() + 1; pos[a[i]].push_back(i); } int B = sqrt(n), cnt = (n + B - 1) / B; // B为每块的长度,cnt为总块数 for (int i = 1; i <= n; i++) { b[i] = (i - 1) / B + 1; } for (int i = 1; i <= cnt; i++) { L[i] = (i - 1) * B + 1; R[i] = min(i * B, n); } // 预处理块到块的众数 for (int i = 1; i <= cnt; i++) { timer++; int max_cnt = 0, mode = 0; for (int j = i; j <= cnt; j++) { for (int k = L[j]; k <= R[j]; k++) { int v = a[k]; if (vis[v] != timer) { vis[v] = timer; tmp_cnt[v] = 0; } tmp_cnt[v]++; if (tmp_cnt[v] > max_cnt || (tmp_cnt[v] == max_cnt && (mode == 0 || vals[v - 1] < vals[mode - 1]))) { max_cnt = tmp_cnt[v]; mode = v; } } f[i][j] = mode; } } for (int i = 1; i <= n; i++) { int l, r; cin >> l >> r; int ans = 0, max_cnt = 0; timer2++; // 获取值v在[l, r]内的出现次数 auto get_cnt = [&](int v, int l, int r) { return upper_bound(pos[v].begin(), pos[v].end(), r) - lower_bound(pos[v].begin(), pos[v].end(), l); }; // 更新众数 auto update = [&](int v) { if (vis2[v] == timer2) return; // 避免重复统计 vis2[v] = timer2; int c = get_cnt(v, l, r); if (ans == 0 || c > max_cnt || (c == max_cnt && vals[v - 1] < vals[ans - 1])) { max_cnt = c; ans = v; } }; if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) update(a[j]); } else { if (b[l] + 1 <= b[r] - 1) { ans = f[b[l] + 1][b[r] - 1]; max_cnt = get_cnt(ans, l, r); vis2[ans] = timer2; // 标记已统计,防止零散块重复统计 } for (int j = l; j <= R[b[l]]; j++) update(a[j]); for (int j = L[b[r]]; j <= r; j++) update(a[j]); } cout << vals[ans - 1] << '\n'; } return 0; } -
0
回滚莫队(离线):
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,B,a[300010],ans[300010],lsh[300010],tsp; struct Q{ int l,r,id; }qq[300010]; bool cmp(Q a,Q b){ if(a.l/B!=b.l/B)return a.l<b.l; return a.r<b.r; } int cnt[300010],cntc[300010],cntl[300010],mx,s,vis[300010]; int calc(int l,int r){ int mx=0,res=0; for(int i=l;i<=r;i++){ cntc[a[i]]++; if(cntc[a[i]]>mx||(cntc[a[i]]==mx&&a[i]<res)){ mx=cntc[a[i]]; res=a[i]; } } for(int i=l;i<=r;i++)cntc[a[i]]=0; return lsh[res]; } void add(int v){ cnt[v]++; if(cnt[v]>mx||(cnt[v]==mx&&v<s)){ mx=cnt[v];s=v; } } void addl(int v){ if(vis[v]<tsp){ vis[v]=tsp; cntl[v]=cnt[v]; } cntl[v]++; if(cntl[v]>mx||(cntl[v]==mx&&v<s)){ mx=cntl[v]; s=v; } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n; B=sqrt(n); for(int i=1;i<=n;i++){ cin>>a[i]; lsh[i]=a[i]; } sort(lsh+1,lsh+1+n); int ln=unique(lsh+1,lsh+1+n)-lsh-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(lsh+1,lsh+1+ln,a[i])-lsh; cin>>qq[i].l>>qq[i].r;qq[i].id=i; } sort(qq+1,qq+1+n,cmp); for(int i=0,j=1;i<=n/B;i++){ int R=min(n,(i+1)*B-1); memset(cnt,0,sizeof(cnt)); mx=s=0; tsp++; int l=R+1,r=R; for(;j<=n&&qq[j].l/B==i;j++){ if(qq[j].r/B==qq[j].l/B){ ans[qq[j].id]=calc(qq[j].l,qq[j].r); continue; } while(r<qq[j].r)add(a[++r]); int nmx=mx,ns=s; tsp++; while(l>qq[j].l)addl(a[--l]); ans[qq[j].id]=lsh[s]; mx=nmx;s=ns; l=R+1; } } for(int i=1;i<=n;i++){ cout<<ans[i]<<'\n'; } return 0; }分块(在线):
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mxn=3e5+10,mxl=550; int n,a[mxn],L[mxl],R[mxl],s[mxl][mxn],z[mxl][mxl],p[mxn],tt[mxn],cnt,B,ln,lsh[mxn]; void init(){ for(int i=1;;i++){ L[i]=(i-1)*B+1;R[i]=min(n,i*B); if(R[i]==n){ cnt=i; break; } } for(int i=1;i<=n;i++)p[i]=(i+B-1)/B; for(int i=1;i<=cnt;i++){ for(int j=L[i];j<=R[i];j++){ tt[a[j]]++; } for(int j=1;j<=ln;j++)s[i][j]=tt[j]; } for(int i=1;i<=cnt;i++){ memset(tt,0,sizeof(tt)); int mx=ln; for(int j=i;j<=cnt;j++){ for(int k=L[j];k<=R[j];k++){ tt[a[k]]++; if(tt[a[k]]>tt[mx]||(tt[a[k]]==tt[mx]&&a[k]<mx))mx=a[k]; } z[i][j]=mx; } } } int find(int l,int r){ if(p[l]==p[r]){ for(int i=l;i<=r;i++)tt[a[i]]=0; int mx=ln; tt[ln]=0; for(int i=l;i<=r;i++){ tt[a[i]]++; if(tt[a[i]]>tt[mx]||(tt[a[i]]==tt[mx]&&a[i]<mx))mx=a[i]; } return lsh[mx]; } int mx=(p[l]+1<=p[r]-1?z[p[l]+1][p[r]-1]:ln); tt[mx]=s[p[r]-1][mx]-s[p[l]][mx]; for(int i=l;i<=R[p[l]];i++)tt[a[i]]=s[p[r]-1][a[i]]-s[p[l]][a[i]]; for(int i=L[p[r]];i<=r;i++)tt[a[i]]=s[p[r]-1][a[i]]-s[p[l]][a[i]]; for(int i=l;i<=R[p[l]];i++){ tt[a[i]]++; if(tt[a[i]]>tt[mx]||(tt[a[i]]==tt[mx]&&a[i]<mx))mx=a[i]; } for(int i=L[p[r]];i<=r;i++){ tt[a[i]]++; if(tt[a[i]]>tt[mx]||(tt[a[i]]==tt[mx]&&a[i]<mx))mx=a[i]; } return lsh[mx]; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n; B=sqrt(n); for(int i=1;i<=n;i++){ cin>>a[i]; lsh[i]=a[i]; } sort(lsh+1,lsh+1+n); ln=unique(lsh+1,lsh+1+n)-lsh-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(lsh+1,lsh+1+ln,a[i])-lsh; } init(); for(int i=1;i<=n;i++){ int l,r; cin>>l>>r; cout<<find(l,r)<<'\n'; } return 0; }
- 1
信息
- ID
- 477
- 时间
- 1500ms
- 内存
- 1024MiB
- 难度
- 8
- 标签
- 递交数
- 38
- 已通过
- 6
- 上传者