zoukankan      html  css  js  c++  java
  • #6285. 数列分块入门 9(区间的最小众数 离散化+数列分块)

    题目链接:https://loj.ac/problem/6285

    题目大意:中文题目

    论文链接:

     https://wenku.baidu.com/view/99bf0fc78662caaedd3383c4bb4cf7ec4afeb628.html 

    具体思路:dp[i][j]表示第i块到第j块的的众数是谁,然后每一次询问先询问两旁不完整的块,然后中间的整块o(1)询问就可以了。

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<stdio.h>
     4 #include<cmath>
     5 #include<vector>
     6 #include<string>
     7 #include<cstring>
     8 #include<algorithm>
     9 using namespace std;
    10 # define ll long long
    11 const int maxn = 2e5+100;
    12 vector<int>q[maxn];
    13 vector<int>vis;
    14 int belong[maxn],a[maxn];
    15 int num[maxn];
    16 int dp[2500][2500];
    17 int n,block=50;
    18 void init(int x){
    19 memset(num,0,sizeof(num));
    20 int maxx=0,ans=0;
    21 for(int i=(x-1)*block+1;i<=n;i++){
    22 num[a[i]]++;
    23 if(num[a[i]]>maxx||(num[a[i]]==maxx&&ans>a[i])){
    24 maxx=num[a[i]];
    25 ans=a[i];
    26 }
    27 dp[x][belong[i]]=ans;
    28 }
    29 }
    30 int cal(int st,int ed,int num){//返回的是下标,所以对于结尾是upper,对于开始是lower
    31 return upper_bound(q[num].begin(),q[num].end(),ed)-lower_bound(q[num].begin(),q[num].end(),st);
    32 }
    33 int  ask(int st,int ed){
    34 int maxx=0,ans=0;
    35 if(belong[st]==belong[ed]){
    36 for(int i=st;i<=ed;i++){
    37 int tmp=cal(st,ed,a[i]);
    38 if(maxx<tmp||(maxx==tmp&&ans>a[i])){
    39 ans=a[i];
    40 maxx=tmp;
    41 }
    42 }
    43 return ans;
    44 }
    45 for(int i=st;i<=min(ed,(belong[st]*block));i++){
    46 int tmp=cal(st,ed,a[i]);
    47 if(maxx<tmp||(maxx==tmp&&ans>a[i])){
    48 ans=a[i];
    49 maxx=tmp;
    50 }
    51 }
    52 for(int i=(belong[ed]-1)*block+1;i<=ed;i++){
    53 int tmp=cal(st,ed,a[i]);
    54 if(maxx<tmp||(maxx==tmp&&ans>a[i])){
    55 ans=a[i];
    56 maxx=tmp;
    57 }
    58 }
    59 int tmp=cal(st,ed,dp[belong[st]+1][belong[ed]-1]);
    60 if(maxx<tmp||(maxx==tmp&&ans>dp[belong[st]+1][belong[ed]-1])){
    61 ans=dp[belong[st]+1][belong[ed]-1];
    62 maxx=tmp;
    63 }
    64 return ans;
    65 }
    66 int main(){
    67 scanf("%d",&n);
    68 for(int i=1;i<=n;i++){
    69 scanf("%d",&a[i]);
    70 vis.push_back(a[i]);
    71 belong[i]=(i-1)/block+1;
    72 }
    73 sort(vis.begin(),vis.end());
    74 vis.erase(unique(vis.begin(),vis.end()),vis.end());//离散化
    75 for(int i=1;i<=n;i++){
    76 a[i]=lower_bound(vis.begin(),vis.end(),a[i])-vis.begin();
    77 }
    78 for(int i=1;i<=belong[n];i++){
    79 init(i);//求dp[i][j]
    80 }
    81 for(int i=1;i<=n;i++){
    82 q[a[i]].push_back(i);
    83 }
    84 int Case=n,st,ed;
    85 while(Case--){
    86 scanf("%d %d",&st,&ed);
    87 printf("%d
    ",vis[ask(st,ed)]);
    88 }
    89 return 0;
    90 }
  • 相关阅读:
    CF110A Nearly Lucky Number
    Max Sum Plus Plus HDU – 1024
    洛谷 p1003 铺地毯
    poj-1226
    Where is the Marble? UVA – 10474
    Read N Characters Given Read4
    Guess Number Higher or Lower && 九章二分法模板
    Intersection of Two Arrays II
    Reverse Vowels of a String
    Meeting Rooms
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10478654.html
Copyright © 2011-2022 走看看