标签:
筛法+划分树。
枚举因子,类似筛法计算因子数量,复杂度为n/2 + n/3 + ... + n/n ≈ O(nlogn)。
值域已知,只有删除操作,寻找kth,用划分树就好了O(nlogn)。二分+树状数组也可以,只是复杂度多乘一个logn。
/********************************************************* * ------------------ * * author AbyssalFish * **********************************************************/ #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> #include<cmath> #include<numeric> using namespace std; const int MAX_SIZE = 1<<20, MAX_N = 5e5, LEN = 11; int s[MAX_SIZE]; int N, K; #define para int o = 1, int l = 0,int r = N-1 #define Tvar int mid = (l+r)>>1, lc = (o<<1), rc = (o<<1|1); #define lsn lc, l, mid #define rsn rc, mid+1, r void build(para) { s[o] = r-l+1; if(l == r) return; else { Tvar build(lsn); build(rsn); } } int q_modify(int k, para) { s[o]--; if(l == r){ return l; } else { Tvar if(k<=s[lc]) return q_modify(k, lsn); return q_modify(k-s[lc], rsn); } } char name[MAX_N][LEN]; int card[MAX_N]; int Fp[MAX_N+1]; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif //cout<<(1<<20);//ceil(log2(5e5)+1); scanf("%d%d",&N,&K); for(int i = 2; i <= N; i++){ for(int j = i; j <= N; j += i){ Fp[j]++; } } int tar = 1; for(int i = 2; i <= N; i++){ if(Fp[tar] < Fp[i]) tar = i; } for(int i = 0; i < N; i++) scanf("%s%d", name[i], card+i); build(); int pos , kth = K-1, mn = N-tar; for(int n = N; n-- > mn; ){ pos = q_modify(kth+1); if(n){ if(card[pos] > 0) card[pos]--; //可以看作往后移动一下,然后把kth去掉 kth = (card[pos]+kth)%n; if(kth < 0) kth += n; } } printf("%s %d\n", name[pos], Fp[tar]+1); return 0; }
POJ - 2886 Who Gets the Most Candies
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4977437.html