• 洛谷 P4168 蒲公英 分块入门


    我学分块入门的第二题,其实它应该作为第一题做的

    虽然之前做过一道类似的题目:作诗, 但是还是调试了很长的时间, 很多细节的地方经常搞错

    看来代码还是得多练

    先记录一下代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 using namespace std;
      7 const int maxn = 40010;
      8 const int maxm = 210;
      9 
     10 struct u {
     11     int v,i;
     12     bool operator < (const u &rhs) const {
     13       return v < rhs.v;
     14     }
     15 }B[maxn];
     16 
     17 int n, m, N, S, c;
     18 int A[maxn], F[maxm][maxm], G[maxm][maxn], ID[maxn], cnt[maxn], cntM[maxn];
     19 int rk[maxn], col[maxn], frk[maxn];
     20 
     21 bool cmp(u x,u y) {
     22     return x.i < y.i;
     23 }
     24 
     25 void lsh() {
     26     sort(B+1,B+n+1);
     27     for(int i = 1;i <= n;i++) {
     28         if(B[i].v != col[B[i-1].v]) c++;
     29         col[c] = B[i].v;
     30         B[i].v = c;
     31     }
     32     sort(B+1,B+n+1,cmp);
     33     for(int i = 1;i <= n;i++) A[i] = B[i].v;
     34 }
     35 
     36 int query(int x,int y,int t) {
     37     int ret = 0, MX, MX_i;
     38     
     39     if(ID[x] + 1 >= ID[y]) {
     40       MX = 0, MX_i = 0;
     41         for(int i = x;i <= y;i++) {
     42             if(cntM[A[i]] != t) {
     43                 cntM[A[i]] = t;
     44                 cnt[A[i]] = 0;
     45             }
     46             cnt[A[i]]++;
     47             int tp = cnt[A[i]];
     48             if(tp > MX || (tp == MX && A[i] < MX_i)) {
     49                 MX = tp;
     50                 MX_i = A[i];
     51             }
     52         }
     53         return col[MX_i];
     54     }
     55     
     56     ret = F[ID[x]+1][ID[y]-1];
     57     MX = G[ID[y]-1][ret] - G[ID[x]][ret], MX_i = ret;
     58     for(int i = x;i <= y;) {
     59         if(cntM[A[i]] != t) {
     60             cntM[A[i]] = t;
     61             cnt[A[i]] = 0;
     62         }
     63     
     64         cnt[A[i]]++;
     65         int tp = cnt[A[i]] + G[ID[y]-1][A[i]] - G[ID[x]][A[i]];
     66         //cout<<ID[y-1]*S+1<<endl; 
     67         if(tp > MX || (tp == MX && A[i] < MX_i)) {
     68             MX = tp;
     69             MX_i = A[i];
     70         }
     71         
     72         if(i == ID[x]*S) i = (ID[y]-1)*S+1;
     73         else i++;
     74     }
     75     
     76     return col[MX_i];
     77 }
     78 
     79 int main() {
     80     //freopen("d.txt","r",stdin);
     81     scanf("%d %d",&n,&m);
     82     S = sqrt(n);
     83     N = (n-1)/S + 1;
     84     for(int i = 1;i <= n;i++) {
     85         scanf("%d",&A[i]);
     86         B[i].v = A[i];
     87         B[i].i = i;
     88         ID[i] = (i-1)/S + 1;
     89     }
     90     
     91     lsh();
     92     
     93     int Max = 0, Max_i = n+1;
     94     for(int i = 1;i <= N;i++) {
     95         int t = i;
     96         Max = 0;
     97         Max_i = 0;
     98         for(int j = S*(i-1)+1; j <= n;j++) {
     99             int p = ID[j];
    100             if(cntM[A[j]] != t) {
    101                 cnt[A[j]] = 0;
    102                 cntM[A[j]] = t;
    103             }
    104             cnt[A[j]]++;
    105             int tp = cnt[A[j]];
    106             if(tp > Max || (tp == Max && Max_i > A[j])) {
    107                 Max = tp;
    108                 Max_i = A[j];
    109             }
    110             if(j%S == 0) F[i][p] = Max_i;
    111         }
    112     }
    113 
    114     memset(cnt,0,sizeof(cnt));
    115     for(int i = 1;i <= n;i++) {
    116         cnt[A[i]]++;
    117         if(i%S == 0 || i == n) {
    118             for(int j = 1;j <= c;j++) {
    119                 G[ID[i]][j] = cnt[j];
    120             }
    121         }
    122     }
    123 
    124     int ans = 0;
    125     for(int i = 1,x,y;i <= m;i++) {
    126         scanf("%d %d",&x,&y);
    127         x = (x+ans-1)%n + 1;
    128         y = (y+ans-1)%n + 1;
    129         if(x > y) swap(x,y);
    130     //    cout <<x<< " : "<<y<<endl;
    131         ans = query(x,y,i+n);
    132       printf("%d
    ", ans);
    133     }
    134     
    135     return 0;
    136 } 
  • 相关阅读:
    Oracle学习
    WPF中获取DataGrid列表的选中行Id的方法
    调用MySql存储过程的方法 '增删改查'
    MySql中存储过程的基本增删改查操作
    在WinForm中遍历获取TreeView的节点及其子节点
    WinForm获取MySql数据的基本增删改查
    WinForm中的用户控件实现分页功能
    NGUI之自适应屏幕
    快速排序法
    Array,ArrayList、List<T>、HashSet<T>、LinkedList<T>与Dictionary<K,V>
  • 原文地址:https://www.cnblogs.com/frankscode/p/9511929.html
Copyright © 2020-2023  润新知