我是靠谱客的博主 无语蜻蜓,最近开发中收集的这篇文章主要介绍9.14题解T1T2T3T4,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

T1

对于这个数据范围,我们发现我们不断的乘$b$,什么都不加,$b$是最小的2,$T$是最小的1,最多也就乘大概60次就足够了,也就是说我们完全可以枚举乘过几个$b$,既然我们确定了需要乘几个$b$,那加$a$也就可以确定了,我们可以得到$m{times}a=T-S{times}b^x$,我们就可以得到m的值,而关键就是求出$b$进制下的m,这样的话我们就可以直接统计加了几次$a$了,显然是个进制转化,照着二进制乱搞就可以了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define maxx 1001000
 5 #define ll long long
 6 #define inf 2000000000000000000
 7 using namespace std;
 8 ll S,T,a,b,base=1,m,ans=inf;
 9 ll ksm(ll a,int b)
10 {
11
ll ans=1;
12
while(b)
13 
{
14
if(b&1)
ans*=a;
15
b=b>>1;
a*=a;
16 
}
17
return ans;
18 }
19 int main()
20 {
21
scanf("%lld%lld%lld%lld",&S,&T,&a,&b);
22
for(int i=0;i<=64;++i)
23 
{
24
if(base>T/S)
break;
25
ll cha=T-S*base;
26
if(cha%a==0)
m=cha/a;
27
else
{base*=b;
continue;}
28
ll sum=i;
29
for(int j=i;j>=0;--j)
30 
{
31
ll mi=ksm(b,j);
32
sum+=m/mi;
m%=mi;
33 
}
34
base*=b;
ans=min(ans,sum);
35 
}
36
printf("%lldn",ans);
37
return 0;
38 }
View Code

T2

不知道为什么我像失忆了一般,我明明记得我打完了这道题,然而我残存的代码告诉我,我刚开始码他。。。。咕了

T3

他们发现了费用随特殊加热器的使用次数呈单谷函数,我们就可以愉快的开启三分的旅程,怎么$check$呢?考虑贪心,由于我们每次用普通加热器都会覆盖一段区间,所以用树状数组进行差分,首先预处理出来我如果在当前这个点使用普通加热器,最多能覆盖到哪一个点,$check$的时候从第一个点开始,如果还没有达到希望的能量,就使用加热器使他达到,顺带使可以和他一起使用加热器的点需要的能量值变少即可

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<bits/stdc++.h>
 6 #define maxn 100100
 7 #define int long long
 8 using namespace std;
 9 struct node{
10
int l,r;
11 }a[maxn];
12 int n,m,t,co_ba,maxx,l=0,r,head=1,minn=0x7fffffffffffffff;
13 int p[maxn],flag[maxn],c[maxn],to[maxn],sf[maxn];
14 bool cmp(const node &a,const node &b)
15 {
16
return a.l<b.l;
17 }
18 int lowbit(int x)
19 {
20
return x&(-x);
21 }
22 void add(int pos,int w)
23 {
24
for(;pos<=n;pos+=lowbit(pos))
c[pos]+=w;
25 }
26 int query(int pos)
27 {
28
int ans=0;
29
for(;pos>0;pos-=lowbit(pos))
ans+=c[pos];
30
return ans;
31 }
32 int check(int x)
33 {
34
memset(c,0,sizeof(c));
35
int sum=x*t;
36
for(int i=1;i<=n;++i)
sf[i]=max(1ll*0,p[i]-x);
37
for(int i=1;i<=n;++i)
add(i,sf[i]-sf[i-1]);
38
for(int i=1;i<=n;++i)
39 
{
40
int ww=query(i);
41
if(ww<=0)
continue;
42
sum+=ww;
add(i,-ww);
add(to[i]+1,ww);
43 
}
44
return sum;
45 }
46 signed main()
47 {
48
scanf("%lld%lld%lld",&n,&m,&t);
49
for(int i=1;i<=n;++i)
scanf("%lld",&p[i]);
50
for(int i=1;i<=m;++i)
51 
{
52
scanf("%lld%lld",&a[i].l,&a[i].r);
53
for(int j=a[i].l;j<=a[i].r;++j)
flag[j]=1;
54 
}
55
sort(a+1,a+m+1,cmp);
56
for(int i=1;i<=n;++i)
57
if(!flag[i])
maxx=max(maxx,p[i]);
58
for(int i=1;i<=n;++i)
{p[i]=max(1ll*0,p[i]-maxx);
r=max(r,p[i]);}
59
co_ba=t*maxx;
maxx=0;
60
for(int i=1;i<=n;++i)
61 
{
62
while(a[head].l<=i&&head<=m)
{maxx=max(maxx,a[head].r);
head++;}
63
to[i]=maxx;
64 
}
65
while(l+1<r)
66 
{
67
int mid=(l+r)>>1;
68
int cost1=check(mid-1),cost2=check(mid);
69
minn=min(minn,cost1);
minn=min(minn,cost2);
70
if(cost1>=cost2)
l=mid;
71
else
r=mid;
72 
}
73
co_ba+=minn;
printf("%lldn",co_ba);
74
return 0;
75 }
View Code

T4

说一下思路过程吧,一开始打了个暴力,枚举连接的两个端点直接求花费,然后只有30分,后来打了个小表发现一个端点确定之后另一个端点可以三分,就有了$T60$的好成绩,然后我就突然发现两个端点似乎可以三分套三分,但是由于中间平的地方太多,单谷不严格,所以三分本来就是死的,三分套三分就死透了,然后我惊讶的得知这道题数据水到随机化可$A$,然后我就$A$了。。。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #define maxn 100010
 4 using namespace std;
 5 struct node{
 6
int l,r;
 7 }q[maxn];
 8 int n,m,head,tail,ans=0x7fffffff;
 9 int check()
10 {
11
int maxx=0;
12
for(int i=1;i<=m;++i)
13 
{
14
int len=q[i].r-q[i].l;
15
if(head>q[i].l&&tail<q[i].r)
len=min(len,head-q[i].l+q[i].r-tail);
16
else if(head<=q[i].l&&tail>=q[i].r)
len=min(q[i].r-q[i].l,q[i].l-head+tail-q[i].r);
17
else if(head>q[i].l&&tail>=q[i].r)
len=min(q[i].r-q[i].l,head-q[i].l+tail-q[i].r);
18
else if(head<=q[i].l&&tail<q[i].r)
len=min(q[i].r-q[i].l,q[i].l-head+q[i].r-tail);
19
maxx=max(maxx,len);
20
if(maxx>=ans)
return maxx;
21 
}
22
return maxx;
23 }
24 int main()
25 {
26
scanf("%d%d",&n,&m);
27
for(int i=1;i<=m;++i)
scanf("%d%d",&q[i].l,&q[i].r);
28
if(m==1)
{printf("0n");
return 0;}
29
for(int i=1;i<=n;++i)
30 
{
31
int l=i+2,r=n;
32
while(l+1<r)
33 
{
34
int mid=(l+r)>>1;
35
head=i;
tail=mid-1;
36
int cost1=check();
37
head=i;
tail=mid;
38
int cost2=check();
39
ans=min(ans,cost1);
ans=min(ans,cost2);
40
if(cost1>=cost2)
l=mid;
41
else
r=mid;
42 
}
43 
}
44
printf("%dn",ans);
45
return 0;
46 }
View Code

 

转载于:https://www.cnblogs.com/hzjuruo/p/11626675.html

最后

以上就是无语蜻蜓为你收集整理的9.14题解T1T2T3T4的全部内容,希望文章能够帮你解决9.14题解T1T2T3T4所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)
立即
投稿
返回
顶部