2019正睿CSP-S模擬賽十連測day7

2019正睿CSP-S模擬賽十連測day7

今天上午剛考完初賽,全員90+,就只有我是80(有可能80-?),慌得一匹,洛谷討論一面又有一堆人估分比我高,還問有沒有救,我原地自閉。教練說一星期後才能出分數線,那我這一個星期看來都要在自閉中度過了。c++

今天這場比賽就是在自閉中度過的,感受沒能很好地集中精力作題,一直在想初賽(也許集中精力也不能打上去?),最後的分數是ide

100+50+0(指望10)=150(rank=25)ui

T1感受仍是比較送的,亂搞之中出正解,玩了玩搞了搞終於在一個小時以後弄了出來,T2有一個一眼的遞歸式,寫了個記憶化上去,T3一看根本連思路都沒有,直接自爆了。this

link to this contestspa

A. dls的生日禮物

  • 首先判掉無解的狀況,就是存在三個區間互相有交
  • 如今對於任意一個位置都最多隻會被兩個區間覆蓋,每一個聯通塊只能相間分佈,兩種狀況,而且與其它聯通塊相獨立,因而答案就是$2^{聯通塊個數}$
 1 #include<bits/stdc++.h>
 2 #define FOR(i,a,b) for (register int i=(a);i<=(b);i++)
 3 #define For(i,a,b) for (register int i=(a);i>=(b);i--)
 4 #define mem(i,j) memset(i,j,sizeof(i))
 5 #define GO(u) for (register int 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<int,int>
11 using namespace std;
12 typedef long long ll;
13 const int N=2e6+5;
14 const int mod=998244353;
15 int n,ans=1,a[N],len=0,t[N],maxr;
16 struct data
17 {
18     int l,r;
19 }f[N];
20 bool cmp(const data x,const data y) 
21 {
22     if (x.l==y.l) return x.r<y.r;
23     return x.l<y.l;
24 }
25 inline int read()
26 {
27     int x=0,f=1;
28     char c=getchar();
29     while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
30     while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
31     return f*x;
32 }
33 inline void write(int x)
34 {
35     if (x<0) putchar('-'),x=-x;
36     if (x>9) write(x/10);
37     putchar(x%10+'0');
38     return;
39 }
40 inline int val(int x) {return lower_bound(a+1,a+len+1,x)-a;}
41 inline void no()
42 {
43     printf("0\n");
44     exit(0);
45 }
46 inline int pan()
47 {
48     FOR(i,1,n) t[f[i].l]++,t[f[i].r]--;
49     FOR(i,1,len) t[i]+=t[i-1];
50     FOR(i,1,len) if (t[i]>2) return 1;
51     return 0;
52 }
53 int main()
54 {
55 //    freopen("data.in","r",stdin);
56 //    freopen("myans.out","w",stdout);
57     n=read();
58     FOR(i,1,n) f[i].l=read(),f[i].r=read(),a[++len]=f[i].l,a[++len]=f[i].r;
59     sort(a+1,a+len+1);
60     len=unique(a+1,a+len+1)-a-1;
61     FOR(i,1,n) f[i].l=val(f[i].l),f[i].r=val(f[i].r);
62     if (pan()) no();
63     sort(f+1,f+n+1,cmp);
64     maxr=0;
65     FOR(i,1,n)
66     {
67         if (f[i].l>=maxr) ans=1LL*ans*2%mod,maxr=f[i].r;
68         else maxr=max(maxr,f[i].r);
69     }
70     write(ans);
71     return 0;
72 }
73 /*
74 9
75 14 18
76 13 15
77 16 17
78 1 3
79 2 5
80 4 7
81 6 8
82 9 10
83 11 12
84 */
View Code

 

B. dls的生日宴會

這題首先有下面這個式子,設$f(n)$爲剩下$n$我的時的答案3d

$$f(n)=\min \{a*k+b+f(\lceil \frac{n}{k+1} \rceil)\}$$code

直接記憶化搜一下就好了,試着把決策點輸出一下發現每一輪的$k$是單調的(還沒發現能夠只取兩個數)blog

  • 遊戲最多進行$\lceil logn \rceil$次,咱們枚舉$m$表示遊戲進行的次數,存在一組$k_i$使得遊戲成功當且僅當$\prod_{i=1}^m (k_i+1) \ge n$
  • 而後咱們又發現當咱們在知足上式成立時,咱們但願$\sum k_i$儘量小,由均值不等式得,咱們但願$k_i$儘量接近,因而一定存在一組最優解使得全部$k_i$取到相鄰的兩個取值
  • 枚舉$m$,給$n$開$m$次方,再快速冪回去,看看大的那個值須要多少個,複雜度$O(T log^2n)$
 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 inf=1e18;
14 ll t,n,a,b,ans;
15 inline ll read()
16 {
17     ll x=0,f=1;
18     char c=getchar();
19     while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
20     while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
21     return f*x;
22 }
23 inline void write(ll x)
24 {
25     if (x<0) putchar('-'),x=-x;
26     if (x>9) write(x/10);
27     putchar(x%10+'0');
28     return;
29 }
30 inline ll qpow(ll x,ll y)
31 {
32     ll ret=1;
33     while (y)
34     {
35         if (y&1) ret=ret*x;
36         y>>=1;
37         x=x*x;
38     }
39     return ret;
40 }
41 int main()
42 {
43     t=read();
44     while (t--)
45     {
46         ans=inf;
47         n=read(),b=read(),a=read();
48         if (n==1) {printf("0\n");continue;}
49         FOR(i,1,30)
50         {
51             ll tmp1=pow(n,1.0/i);
52             ll tmp2=qpow(tmp1,i);
53             ll k=(tmp1-1)*i;
54             while(tmp2<n) tmp2/=tmp1,tmp2*=tmp1+1,k++;
55             ans=min(ans,a*k+b*i);
56         }
57         write(ans),putchar('\n');
58     }
59     return 0;
60 }
View Code
相關文章
相關標籤/搜索