結果
| 問題 |
No.919 You Are A Project Manager
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-03-13 17:53:23 |
| 言語 | Java (openjdk 23) |
| 結果 |
AC
|
| 実行時間 | 885 ms / 3,000 ms |
| コード長 | 5,419 bytes |
| コンパイル時間 | 3,004 ms |
| コンパイル使用メモリ | 80,252 KB |
| 実行使用メモリ | 43,368 KB |
| 最終ジャッジ日時 | 2024-11-22 11:16:31 |
| 合計ジャッジ時間 | 28,525 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 55 |
ソースコード
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.NoSuchElementException;
class BitVector{
long[] small;
int[] big;
int n;
public BitVector(int n) {
this.n=n;
small=new long[n/64+1];
big=new int[n/64+1];
}
void set(int k) {
small[k/64]|=1L<<(k%64);
}
void build() {
for(int i=0;i<big.length;++i) {
big[i]=(i>0?Long.bitCount(small[i-1]):0)+(i>0?big[i-1]:0);
}
}
int access(int k) {
return (int) ((small[k/64]>>>(k%64))&1);
}
//[l,r)
int rank(int l,int r,long m) {
if(l>=r)return 0;
int ret=bitCount(r)-bitCount(l);
return m==1?ret:(r-l-ret);
}
//[0,n)
int bitCount(int n) {
n=Math.min(n, this.n);
if(n<=0)return 0;
--n;
return big[n/64]+Long.bitCount((small[n/64]<<(63-n%64))>>>(63-n%64));
}
}
class WaveletMatrix{
int w=64;
BitVector[] b=new BitVector[w];//b[i]:=&2^{i+1}で安定ソートしたときの第&2^{i}
int[] nz=new int[w];
int n;
final long base=Long.MAX_VALUE/2;
public WaveletMatrix(long[] a) {
n=a.length;
for(int i=0;i<b.length;++i)b[i]=new BitVector(n);
long[][] sorted=new long[n][];
for(int i=0;i<a.length;++i) {
sorted[i]= new long[]{a[i]+base,0};
}
Comparator<long[]> comp=new Comparator<long[]>() {
@Override
public int compare(long[] o1, long[] o2) {
return Long.compare((o1[0]>>>o1[1])&1, (o2[0]>>>o2[1])&1);
}
};
for(int bit=w-1;bit>=0;--bit) {
for(int i=0;i<n;++i)sorted[i][1]=bit+1;
if(bit<w-1)Arrays.sort(sorted, comp);//安定ソート
for(int i=0;i<n;++i)if(((sorted[i][0]>>>bit)&1)==1) {
b[bit].set(i);
}
}
for(int i=0;i<b.length;++i)b[i].build();
for(int i=0;i<b.length;++i)nz[i]=b[i].rank(0, n, 0);
}
long access(int k) {
long ret=0;
int pos=k;
for(int bit=w-1;bit>=0;--bit) {
int v=b[bit].access(pos);
ret|=(1L<<bit)*v;
pos=b[bit].rank(0, pos, v)+(v==0?0:nz[bit]);
}
return ret-base;
}
long quantile(int l,int r,int k) {
if(k+1>r-l)throw new AssertionError();
long ret=0;
for(int bit=w-1;bit>=0;--bit) {
int nl=-1,nr=-1;
if(b[bit].rank(l, r, 0)>=k+1) {
nl=b[bit].rank(0, l, 0);
nr=nl+b[bit].rank(l, r, 0);
}else {
nl=nz[bit]+b[bit].rank(0, l, 1);
nr=nl+b[bit].rank(l, r, 1);
k-=b[bit].rank(l, r, 0);
ret|=1L<<bit;
}
l=nl;r=nr;
}
return ret-base;
}
}
class Main {
public static void main(String[] args) {
new Main().run();
}
void run() {
FastScanner sc=new FastScanner();
int N=sc.nextInt();
long[] a=new long[N];
for(int i=0;i<N;++i)a[i]=sc.nextLong();
WaveletMatrix wm=new WaveletMatrix(a);
PrintWriter pw=new PrintWriter(System.out);
long ans=0;
long[] right=new long[N];
long[] left=new long[N];
for(int K=1;K<=N;++K) {
for(int i=0;i<N/K;++i)right[i]=wm.quantile(N-(i+1)*K, N-i*K, (K+1)/2-1)+(i>0?right[i-1]:0);
for(int i=0;i<N/K;++i)left[i]=wm.quantile(i*K, (i+1)*K, (K+1)/2-1)+(i>0?left[i-1]:0);
for(int i=1;i<N/K;++i)right[i]=Math.max(right[i], right[i-1]);
for(int i=1;i<N/K;++i)left[i]=Math.max(left[i], left[i-1]);
for(int i=-1;i<N/K;++i)ans=Math.max(ans, K*((i==-1?0:left[i])+(N/K-i-2==-1?0:right[N/K-i-2])));
}
pw.println(ans);
pw.close();
}
void tr(Object...objects) {System.out.println(Arrays.deepToString(objects));}
}
class FastScanner {
private final InputStream in = System.in;
private final byte[] buffer = new byte[1024];
private int ptr = 0;
private int buflen = 0;
private boolean hasNextByte() {
if (ptr < buflen) {
return true;
}else{
ptr = 0;
try {
buflen = in.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
if (buflen <= 0) {
return false;
}
}
return true;
}
private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
public String next() {
if (!hasNext()) throw new NoSuchElementException();
StringBuilder sb = new StringBuilder();
int b = readByte();
while(isPrintableChar(b)) {
sb.appendCodePoint(b);
b = readByte();
}
return sb.toString();
}
public long nextLong() {
if (!hasNext()) throw new NoSuchElementException();
long n = 0;
boolean minus = false;
int b = readByte();
if (b == '-') {
minus = true;
b = readByte();
}
if (b < '0' || '9' < b) {
throw new NumberFormatException();
}
while(true){
if ('0' <= b && b <= '9') {
n *= 10;
n += b - '0';
}else if(b == -1 || !isPrintableChar(b)){
return minus ? -n : n;
}else{
throw new NumberFormatException();
}
b = readByte();
}
}
public int nextInt() {
long nl = nextLong();
if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
return (int) nl;
}
public double nextDouble() { return Double.parseDouble(next());}
}