題目地址:HDU 5172
比賽的時候用一個維護了區間和,區間積,區間最值的線段樹水過去了。。賽後數據改回10^6後,就TLE了。。
正解是區間和用前綴和維護就可以。然後維護一個該位上的數上一個出現額位置,那麼每次查詢,如果每個數的上一個出現的位置都小於l的話,那麼就說明沒有重復的,如果區間和符合全排列的和,那麼就說明肯定是一個全排列了。
代碼如下:
#include #include #include #include #include #include #include #include #include using namespace std; #define LL __int64 #define pi acos(-1.0) const int mod=1e9+7; const int INF=0x3f3f3f3f; const double eqs=1e-9; #define root 1, n, 1 #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 int a[1000002], pre[1000002], pos[1000002]; int Max[4000000]; LL sum[1000002]; void PushUp(int rt) { Max[rt]=max(Max[rt<<1],Max[rt<<1|1]); } void build(int l, int r, int rt) { if(l==r){ Max[rt]=pre[l]; return ; } int mid=l+r>>1; build(lson); build(rson); PushUp(rt); } int Query(int ll, int rr, int l, int r, int rt) { if(ll<=l&&rr>=r){ return Max[rt]; } int mid=l+r>>1, ans=-1; if(ll<=mid) ans=max(ans,Query(ll,rr,lson)); if(rr>mid) ans=max(ans,Query(ll,rr,rson)); return ans; } int main() { int n, m, i, j, x, l, r, ans; while(scanf("%d%d",&n,&m)!=EOF){ memset(pos,-1,sizeof(pos)); sum[0]=0; for(i=1;i<=n;i++){ scanf("%d",&x); pre[i]=pos[x]; pos[x]=i; sum[i]=sum[i-1]+x; } build(root); while(m--){ scanf("%d%d",&l,&r); if(sum[r]-sum[l-1]!=(LL)(r-l+1)*(r-l+2)/2){ puts("NO"); continue ; } ans=Query(l,r,root); if(ans
最近一直忙著考研復習,很久都沒有更新博客了,今天寫一篇數據結
整個c++程序設計全面圍繞面向對象的方式進行,
// define head function#ifndef
嗅探器這個代碼我去年的時候就已經寫過了,這個學
那些用帶垃圾回收器語言的程序員指出並取笑C++程序員還要去防
二、對象管理與命名空間(Namespace)內