[日常摸魚]統一省選2020(未完)
阿新 • • 發佈:2020-07-29
統一省選2020
前言
這就是卡常大賽嗎,i了i了。
冰火戰士
連結
題解
感覺題目還是簡單的,但是想要現場A掉應該是不容易的(樹狀陣列的就當我沒說),我的第一想法是線段樹。。算是勉強能過。。
直接線段樹的話時間效率是\(O(nlogn)\) ,空間效率也是\(O(nlogn)\) ,然而這樣會\(MLE\) 。容易發現答案一定出現在某個戰士的位置,離散化之後空間效率就可壓到\(O(n)\) 。就可以通過了。。注意常數!注意常數!注意常數!(樹狀陣列的當我沒說)
\(Code\)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<map> #include<set> #define LL long long using namespace std; const int N=2e6+10; const int M=2e9+10; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void print(int x){ if(x>9) print(x/10); putchar(x%10+'0'); } int n,top=0; int opt[N],tt[N],xx[N],yy[N]; int ansl,ansr; int p[N<<1]; struct node{ int ls,rs,v[2]; }a[N]; int get(int x){ int l=1,r=top,mid; while(l<=r){ mid=l+r>>1; if(p[mid]==x) return mid; if(x>p[mid]) l=mid+1; else r=mid-1; } } int main(){ int T,op,l,r,x,i,mid;T=read(); int L,R; for(int j=1;j<=T;++j){ opt[j]=read(); if(opt[j]==1){ tt[j]=read();xx[j]=read();yy[j]=read(); p[++top]=xx[j]; } else{ tt[j]=read(); } } sort(p+1,p+1+top); n=top; for(int i=1;i<=n;++i) if(p[i]!=p[i-1]) p[++top]=p[i]; n=1; for(int j=1;j<=T;++j){ op=opt[j]; if(op==1){ i=j; xx[i]=get(xx[i]); l=1;r=top;x=1; while(1){ a[x].v[tt[i]]+=yy[i]; mid=l+r>>1; if(mid==xx[i]) break; if(xx[i]>mid){ if(!a[x].rs) a[x].rs=++n; l=mid+1;x=a[x].rs; } else { if(!a[x].ls) a[x].ls=++n; r=mid-1;x=a[x].ls; } } } else{ i=tt[j]; l=1;r=top;x=1; while(1){ a[x].v[tt[i]]-=yy[i]; mid=l+r>>1; if(mid==xx[i]) break; if(xx[i]>mid){l=mid+1;x=a[x].rs;} else {r=mid-1;x=a[x].ls;} } } l=1;r=top;x=1;L=0;R=0;ansl=0;ansr=0; while(l<=r){ if(a[x].v[0]+a[x].v[1]){ mid=l+r>>1; op=min(L+a[x].v[0]-a[a[x].rs].v[0],R+a[x].v[1]-a[a[x].ls].v[1]); if(op>ansr||(op==ansr&&mid>ansl)){ansl=mid;ansr=op;} if(L+a[x].v[0]-a[a[x].rs].v[0]<=R+a[x].v[1]-a[a[x].ls].v[1]){ L=L+a[x].v[0]-a[a[x].rs].v[0];l=mid+1;x=a[x].rs; } else{ R=R+a[x].v[1]-a[a[x].ls].v[1];r=mid-1;x=a[x].ls; } } else{ mid=r;op=min(L,R); if(op>ansr||(op==ansr&&mid>ansl)){ansl=mid;ansr=op;} break; } } l=1;r=top;x=1;L=0;R=0; while(l<=r){ if(a[x].v[0]+a[x].v[1]){ mid=l+r>>1; op=min(L+a[x].v[0]-a[a[x].rs].v[0],R+a[x].v[1]-a[a[x].ls].v[1]); if(op==ansr){ if(mid>ansl) ansl=mid; L=L+a[x].v[0]-a[a[x].rs].v[0];l=mid+1;x=a[x].rs; continue; } if(L+a[x].v[0]-a[a[x].rs].v[0]<=R+a[x].v[1]-a[a[x].ls].v[1]){ L=L+a[x].v[0]-a[a[x].rs].v[0];l=mid+1;x=a[x].rs; } else{ R=R+a[x].v[1]-a[a[x].ls].v[1];r=mid-1;x=a[x].ls; } } else{ mid=r;op=min(L,R); if(op>ansr||(op==ansr&&mid>ansl)){ansl=mid;ansr=op;} break; } } if(!ansr) printf("Peace\n"); else { print(p[ansl]);putchar(' ');print(ansr<<1);puts(""); } } return 0; }