Monotonic analysis cf1276C--, thinking

/*
Suppose row <= col, first find the largest area of ​​the matrix (row, col), again regardless of the number entered fill
The current row is row, this matrix in row holds up to the same number of times,
    After the statistics, sorted by number of occurrences, then descending enumeration row, by the number of occurrences of each number, calculated at this time the largest col
Record the maximum row and col, and then fill in the number, the same number can be placed at an angle to fill the number of filling 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 400005
#define ll long long

int am [n], n, a [n], cnt;
map<int,int>mp;
struct Node{int v,cnt;}p[N];
int cmp(Node &a,Node &b){return a.cnt<b.cnt;}

int bin_find ( int Row) { // find the last <= row position 
    int L = 0 , R & lt = CNT, ANS = 0 , MID;
     the while (L <= R & lt) {
        mid=L+R>>1;
        if(p[mid].cnt<=row)
            ans=mid,L=mid+1;
        else R=mid-1;
    }
    return ans;
} 

you do not [N], R, C;
inline int id(int i,int j){return C*(i-1)+j;}
stack<int>stk;
void solve(){
    for(int i=1;i<=cnt;i++)
        for(int j=1;j<=min(p[i].cnt,R);j++)
            stk.push (p [i] .v);
    for(int k=1;k<=C;k++){
        int i=1,j=k;
        while(i<=R && j<=C){
            ma [id (i, j)] = stk.top ();
            stk.pop ();
            ++i,++j;
            if(i>R)break;
            if(j>C)j-=C;
        }
    }
    cout<<R*C<<'\n';
    cout<<R<<" "<<C<<'\n';
    for(int i=1;i<=R;i++){
        for(int j=1;j<=C;j++)
            cout<<ma[id(i,j)]<<" ";
        puts("");
    }
}

int main () {
    cin>>n;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        Mp [A [I]] Tasutasu ;
    }
    
    for(auto x:mp){
        p[++cnt].v=x.first;
        p[cnt].cnt=x.second;
    }
    
    sort(p+1,p+1+cnt,cmp);
    for(int i=1;i<=cnt;i++)
        sum[i]=sum[i-1]+p[i].cnt;
    
    int ansr=0,ansc=0;
    int row=(int)sqrt(n);
    while(row){
        int p=bin_find(row);
        int num=sum[p]+row*(cnt-p);
        int col=num/row;
        if(col>=row && ansr*ansc<col*row){
            ansr=row;ansc=col;
        }
        row--;
    }
    
    R=ansr,C=ansc;
    Solve (); // number of refills 
}
 / *
10000000002
21000000000
02100000000
00210000000
00021000000
12000
01200
00120
00012
20001
*/

Guess you like

Origin www.cnblogs.com/zsben991126/p/12111373.html