CSP-S 2019 is Rui simulation game ten continuous measurement day9
Because of this off for help Boge, score a little water, had about $ 20 + $ name, now is $ 80 + 20 + 40 = 140 (rank = 10) $, but still not be able to take the points have to take the whole ah
A. Cai boss
- First half of an answer, consider how greed can determine whether
- Consider bit by bit from low to high, if this one is $ 1 $ then select an optional set of one of the largest remaining two two packages left to the next level, the next level as an alternative collection
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register ll i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register ll i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register ll j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define MP make_pair 10 #define pii pair<ll,ll> 11 using namespace std; 12 typedef long long ll; 13 const ll N=2e5+5; 14 ll n,k,L,R,MID,er[60],sum=0,tot; 15 ll bit[60]; 16 struct data 17 { 18 ll a,b; 19 }f[N],tmp[N]; 20 multiset <data> s; 21 multiset <data> :: iterator it; 22 vector <data> vec[60]; 23 bool operator <(data x,data y) {return (x.a==x.a)?(x.b>y.b):(x.a<y.a);} 24 inline ll read() 25 { 26 ll x=0,f=1; 27 char c=getchar(); 28 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 29 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 30 return f*x; 31 } 32 inline void write(ll x) 33 { 34 if (x<0) putchar('-'),x=-x; 35 if (x>9) write(x/10); 36 putchar(x%10+'0'); 37 return; 38 } 39 bool cmp(const data x,const data y) {return x.b>y.b;} 40 inline ll check(ll mid) 41 { 42 ll len=0,got=0; 43 while (mid) {bit[++len]=(mid&1),mid>>=1;} 44 s.clear(); 45 FOR(i,1,len) 46 { 47 FOR(j,0,(ll)vec[i-1].size()-1) s.insert(vec[i-1][j]); 48 if (bit[i]) 49 { 50 if (s.size()) 51 { 52 it=s.begin(); 53 got+=(*it).b; 54 s.erase(it); 55 } 56 } 57 tot=0; 58 for (it=s.begin();it!=s.end();it++) tmp[++tot]=(*it); 59 s.clear(); 60 for (register ll i=1;i+1<=tot;i+=2) s.insert((data){i+1,tmp[i].b+tmp[i+1].b}); 61 if (tot&1) s.insert((data){i+1,tmp[tot].b}); 62 } 63 return (got>=k); 64 } 65 int main() 66 { 67 // freopen("data.in","r",stdin); 68 // freopen("myans.out","w",stdout); 69 er[0]=1; 70 FOR(i,1,35) er[i]=er[i-1]<<1; 71 n=read(),k=read(); 72 FOR(i,1,n) f[i].a=read(),f[i].b=read(),sum+=er[f[i].a]; 73 FOR(i,1,n) vec[f[i].a].pb(f[i]); 74 FOR(i,0,35) sort(vec[i].begin(),vec[i].end(),cmp); 75 L=0,R=sum; 76 while (L<R) 77 { 78 MID=(L+R)>>1; 79 if (check(MID)) R=MID; 80 else L=MID+1; 81 } 82 write(L),putchar('\n'); 83 return 0; 84 }
B. The only Rui sauce
- For an interval $ [l, r] $, and $ l-1 $ and $ r + 1 $ number on this position than among larger, if we can immediately know who was the greatest in this range, it is better to do, which is equivalent to the Cartesian tree you plan to make your request, but did not give now, so you enumerate it and see what could be the maximum number of recursive to both sides, this is a sub-issue, multiplied by the number of combinations to
- We are considering how to find the maximum possible position in the interval, we swept from the middle to both sides, if the number happens to come across the border, then it might become a maximum, and $ break $ sideways again because a certain number smaller than it, we find that this process could be the position of the maximum within a range of at most two, we enumerate some pre-change operation can be small
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for (register ll i=(a);i<=(b);i++) 3 #define For(i,a,b) for (register ll i=(a);i>=(b);i--) 4 #define mem(i,j) memset(i,j,sizeof(i)) 5 #define GO(u) for (register ll j=f[u];j!=-1;j=nxt[j]) 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define MP make_pair 10 #define pii pair<ll,ll> 11 using namespace std; 12 typedef long long ll; 13 const ll N=5050; 14 const ll mod=1e9+7; 15 ll n,a[N],f[N][N],ans,L[N],R[N],vis[N]; 16 ll fac[N],inv[N],st1[21][N],st2[21][N]; 17 vector <int> vec[N]; 18 inline ll read() 19 { 20 ll x=0,f=1; 21 char c=getchar(); 22 while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} 23 while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();} 24 return f*x; 25 } 26 inline void write(ll x) 27 { 28 if (x<0) putchar('-'),x=-x; 29 if (x>9) write(x/10); 30 putchar(x%10+'0'); 31 return; 32 } 33 inline ll qpow(ll x,ll y) {ll ret=1;for (;y;y>>=1,x=1LL*x*x%mod) if (y&1) ret=1LL*ret*x%mod;return ret;} 34 inline void init() 35 { 36 fac[0]=1; 37 FOR(i,1,n) fac[i]=1LL*fac[i-1]*i%mod; 38 inv[n]=qpow(fac[n],mod-2); 39 For(i,n-1,0) inv[i]=1LL*inv[i+1]*(i+1)%mod; 40 return; 41 } 42 inline ll C(ll x,ll y) {return 1LL*fac[x]*inv[y]%mod*inv[x-y]%mod;} 43 inline void upd(ll &x,ll y) {x=(1LL*x+y)%mod;return;} 44 inline void build_st() 45 { 46 FOR(i,1,n) st1[0][i]=L[i],st2[0][i]=R[i]; 47 FOR(j,1,20) FOR(i,1,n-(1<<j)+1) 48 { 49 st1[j][i]=min(st1[j-1][i],st1[j-1][i+(1<<(j-1))]); 50 st2[j][i]=max(st2[j-1][i],st2[j-1][i+(1<<(j-1))]); 51 } 52 return; 53 } 54 inline int query1(int l,int r) 55 { 56 int step=log2(r-l+1); 57 return min(st1[step][l],st1[step][r-(1<<step)+1]); 58 } 59 inline int query2(int l,int r) 60 { 61 int step=log2(r-l+1); 62 return max(st2[step][l],st2[step][r-(1<<step)+1]); 63 } 64 inline ll solve(ll l,ll r) 65 { 66 if (l>r) return 1; 67 if (l==r) return f[l][r]=1; 68 if (f[l][r]!=-1) return f[l][r]; 69 if (query1(l,r)<l) return f[l][r]=0; 70 if (query2(l,r)>r) return f[l][r]=0; 71 if (l==3&&r==5) 72 { 73 int cut=1; 74 } 75 ll sum=0; 76 FOR(i,0,(int)vec[l].size()-1) 77 { 78 int pos=vec[l][i]; 79 if (pos-a[pos]!=l&&pos+a[pos]!=r) continue; 80 if (pos<l||pos>r) continue; 81 ll tmp=1LL*solve(l,pos-1)*solve(pos+1,r)%mod*C(r-l,r-pos)%mod; 82 upd(sum,tmp); 83 vis[pos]=1; 84 } 85 FOR(i,0,(int)vec[r].size()-1) 86 { 87 int pos=vec[r][i]; 88 if (pos-a[pos]!=l&&pos+a[pos]!=r) continue; 89 if (pos<l||pos>r) continue; 90 if (vis[pos]) continue; 91 ll tmp=1LL*solve(l,pos-1)*solve(pos+1,r)%mod*C(r-l,r-pos)%mod; 92 upd(sum,tmp); 93 } 94 FOR(i,0,(int)vec[l].size()-1) vis[vec[l][i]]=0; 95 f[l][r]=sum; 96 return sum; 97 } 98 int main() 99 { 100 mem(f,-1); 101 n=read(); 102 init(); 103 FOR(i,1,n) a[i]=read(); 104 FOR(i,1,n) L[i]=i-a[i],R[i]=i+a[i]; 105 build_st(); 106 FOR(i,1,n) vec[i-a[i]].pb(i),vec[i+a[i]].pb(i); 107 FOR(i,1,n) 108 { 109 sort(vec[i].begin(),vec[i].end()); 110 vec[i].resize(unique(vec[i].begin(),vec[i].end())-vec[i].begin()); 111 } 112 ans=solve(1,n); 113 write(ans),putchar('\n'); 114 // FOR(i,1,n-1) FOR(j,i,n) printf("[%d,%d]=%d\n",i,j,f[i][j]); 115 return 0; 116 }