# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
132051 | dragonslayerit | Fish (IOI08_fish) | C++14 | 3052 ms | 10132 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <cstdio>
#include <algorithm>
//Strategy:
//Sort fishes by size
//Relabel gems by last appearance (e.g. gem of largest fish is 0)
//count multisets of gems => count multisets of fish such that if a fish is chosen, all smaller fish with same gem are chosen
//For the actual subset of fish, some gem will be chosen to be "boosted" to the largest fish with that gem.
//Iterate over last fish in multiset (pre-boosting) and count number of valid subsets
//A multiset is bad iff no gem in the prefix is present and the largest fish's gem cannot be boosted.
int cps[500005];
int cps_size=0;
int freq[500005];
int freq2[500005];
int last[500005];
int half[500005];
int prev[500005];
struct Fish{
int size,gem;
bool operator<(Fish f)const{
return size<f.size;
}
}fishes[500005];
int main(){
int N,K,MOD;
scanf("%d %d",&N,&K);
scanf("%d",&MOD);
for(int i=0;i<N;i++){
scanf("%d %d",&fishes[i].size,&fishes[i].gem);
fishes[i].gem--;
}
std::sort(fishes,fishes+N);
//Relabel gems by last appearance
std::fill(cps,cps+K,-1);
for(int i=N-1;i>=0;i--){
if(cps[fishes[i].gem]==-1){
cps[fishes[i].gem]=cps_size++;
}
}
for(int i=0;i<N;i++){
fishes[i].gem=cps[fishes[i].gem];
}
for(int k=0;k<K;k++){
last[k]=-1;
}
for(int i=0;i<N;i++){
prev[i]=last[fishes[i].gem];
last[fishes[i].gem]=i;
//printf("prev[%d]=%d\n",i,prev[i]);
}
/*
for(int i=0;i<N;i++){
printf("i=%d size=%d gem=%d\n",i,fishes[i].size,fishes[i].gem);
}
*/
for(int k=0;k<K;k++){
int low=-1,high=N;
while(high-low>1){
int mid=(low+high)/2;
if(fishes[mid].size*2<=fishes[last[k]].size){
low=mid;
}else{
high=mid;
}
}
half[k]=high;
//half[k] is index of first fish larger than fishes[last[k]].size/2
//for(int& j=half[k]=0;fishes[j].size*2<=fishes[last[k]].size;j++);
}
int ans=0;
int prefix=K-1;//largest gem # that can be "boosted"
for(int i=0;i<N;i++){
freq[fishes[i].gem]++;
while(prefix>=0&&fishes[last[prefix]].size<2*fishes[i].size) prefix--;
//printf("i=%d boostable gem prefix=[0,%d]\n",i,prefix);
//Counting configurations where fishes[i].gem occurs exactly freq[fishes[i].gem] times
//Subtract multisets where none in prefix exist to be boosted
{
int product=1;
for(int k=prefix+1;k<K;k++){
if(k==fishes[i].gem) continue;
product=1LL*product*(freq[k]+1)%MOD;
}
ans=(ans+MOD-product)%MOD;
}
//Add back multisets where none in prefix exist to be boosted but fishes[i] can be boosted
//using frequencies from last fish whose size <=1/2*size of last fish with fishes[i].gem
if(prev[i]!=-1&&fishes[prev[i]].size*2>fishes[last[fishes[i].gem]].size){
//printf("SKIP %d\n",i);
continue;
}
{
std::fill(freq2,freq2+K,0);
for(int j=0;j<std::min(i,half[fishes[i].gem]);j++){
freq2[fishes[j].gem]++;
}
/*
if(freq2[fishes[i].gem]!=freq[fishes[i].gem]-1){
printf("SKIP %d\n",i);
continue;
}
*/
int product=1;
for(int k=prefix+1;k<K;k++){
if(k==fishes[i].gem) continue;
product=1LL*product*(freq2[k]+1)%MOD;
}
//printf("\n");
ans=(ans+product)%MOD;
//printf("i=%d, j=%d: Add %d\n",i,j,product);
}
}
//Count all multisets and subtract bad ones
int all=1;
for(int k=0;k<K;k++){
all=1LL*all*(freq[k]+1)%MOD;
}
//-1 for empty set
ans=(ans+all+MOD-1)%MOD;
printf("%d\n",ans);
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |