CSP-S 2019 is Rui simulation game ten continuous measurement day9

CSP-S 2019 is Rui simulation game ten continuous measurement day9

link to this contest

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
 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 }
View Code

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
  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 }
View Code

 

Guess you like

Origin www.cnblogs.com/C-S-X/p/11784854.html