제출 #66714

#제출 시각아이디문제언어결과실행 시간메모리
66714zetapi코끼리 (Dancing Elephants) (IOI11_elephants)C++14
10 / 100
3 ms596 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define ll int #define itr ::iterator typedef pair<int,int> pii; const int MAX=3e6; pii blocks[MAX]; int ROOT,SizeOfBlock,dp[MAX],BlockNumber[MAX],Index[1100][1100]; int N,K,qcnt,ptr,start,pos[MAX],nxt[MAX],pre[MAX],covered[MAX],arr[MAX]; void recalculate(ll idx) { int start_=blocks[idx].first,end_=blocks[idx].second,lol=start_,lop=1; pre[start_]=0; Index[idx][1]=start_; for(int A=nxt[start_];A!=nxt[end_];A=nxt[A]) { pre[A]=lol; lol=A; Index[idx][++lop]=A; } for(int A=lop+1;Index[idx][A]>0;A++) Index[idx][A]=0; int cov=end_,cnt=1,ptr1=end_; for(int A=end_;A>0;A=pre[A]) { if(arr[cov]-arr[A]>K) { cov=A; ++cnt; } dp[A]=cnt; if(dp[A]==1) covered[A]=arr[A]+K; else { while(arr[pre[ptr1]]-arr[A]>K) ptr1=pre[ptr1]; covered[A]=covered[ptr1]; } } return ; } void build() { SizeOfBlock=0; ll lol=0; for(int A=0;A<=ROOT;A++) for(int B=0;Index[A][B]>0;B++) Index[A][B]=0; for(int A=start;A>0;A=nxt[A]) { BlockNumber[A]=SizeOfBlock; Index[BlockNumber[A]][++lol]=A; if(lol==ROOT or nxt[A]==0) { blocks[SizeOfBlock++]=mp(Index[BlockNumber[A]][1],A); lol=0; } } for(int A=0;A<SizeOfBlock;A++) recalculate(A); return ; } void remove(ll idx,ll val) { if(idx==start) { start=nxt[start]; blocks[0].first=start; recalculate(BlockNumber[idx]); return ; } for(int A=blocks[BlockNumber[idx]].first;nxt[A]>0;A=nxt[A]) { if(A==idx) { A=blocks[BlockNumber[idx]-1].second; assert(nxt[A]==idx); } if(nxt[A]==idx) { nxt[A]=nxt[nxt[A]]; if(idx==blocks[BlockNumber[idx]].first) blocks[BlockNumber[idx]].first=nxt[A]; else if(idx==blocks[BlockNumber[idx]].second) blocks[BlockNumber[idx]].second=A; break; } } recalculate(BlockNumber[idx]); return ; } void insert(ll idx,ll val) { if(val<=arr[start]) { nxt[idx]=start; start=idx; BlockNumber[idx]=0; blocks[0].first=start; recalculate(BlockNumber[idx]); } else { ll lol=start; for(int A=start;A>0;A=nxt[A]) if(val>=arr[A]) lol=A; nxt[idx]=nxt[lol]; nxt[lol]=idx; BlockNumber[idx]=BlockNumber[lol]; if(lol==blocks[BlockNumber[lol]].second) blocks[BlockNumber[lol]].second=idx; recalculate(BlockNumber[idx]); } /*else { int low=0,high=SizeOfBlock-1,mid,res=0,lol=0; while(low<=high) { mid=(low+high)/2; if(val>=arr[blocks[mid].first]) res=mid,low=mid+1; else high=mid-1; } assert(val>=arr[blocks[res].first]); for(int A=blocks[res].first;A!=nxt[blocks[res].second];A=nxt[A]) { if(arr[A]<=val) lol=A; if(arr[A]==A) break; } nxt[idx]=nxt[lol]; nxt[lol]=idx; BlockNumber[idx]=BlockNumber[lol]; if(lol==blocks[BlockNumber[lol]].second) blocks[BlockNumber[lol]].second=idx; recalculate(BlockNumber[idx]); }*/ return ; } ll count(ll CurrentBlock,ll CoveredTill) { if(CurrentBlock>=SizeOfBlock) return 0; ll low=1,high=ROOT+1,mid,res=-1; while(low<=high) { mid=(low+high)/2; if(Index[CurrentBlock][mid]==0) high=mid-1; else if(arr[Index[CurrentBlock][mid]]<=CoveredTill) res=Index[CurrentBlock][mid], low=mid+1; else high=mid-1; } if(res==blocks[CurrentBlock].second) return count(CurrentBlock+1,CoveredTill); else if(res<0) res=blocks[CurrentBlock].first; else res=nxt[res]; return dp[res]+count(CurrentBlock+1,covered[res]); } void init(int n,int l,int X[]) { N=n; K=l; ptr=n; start=1; ROOT=sqrt(n)+1; for(int A=1;A<=N;A++) { pos[A]=A; nxt[A]=A+1; arr[A]=X[A-1]; } nxt[N]=0; build(); return ; } int update(int i,int y) { if(N==1) return 1; ++i; ++ptr; ++qcnt; remove(pos[i],y); pos[i]=ptr; arr[ptr]=y; insert(pos[i],y); if(qcnt%ROOT==0) { qcnt=0; build(); } return count(0,-1); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...