补锅之校内测(桶哥系列)

刚把吃桶吃出来,就告诉我推荐生凉了

中考完我又(欠着一大堆没有写的博客以及作业) 回来了

几乎拖了一个月的博客

感谢lz帮我保留了吃桶的代码

%%%lz

T1买桶

看到如此大的数据

1:开long long 判断a>=b*c,显然这不优雅

2:判断a/b>=c或a/c>=b,坑来了,b,c可以为0

 ac代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
long long a,b,c;
int main()
{
    scanf("%lld%lld%lld",&a,&b,&c);//不知为何脑抽的开了long long
    if(b==0)
    {printf("Yes");return 0;
    }
    if(a/b>=c)printf("Yes");
    else printf("No");
}

 

T2送桶

我们看这个样例分析,好像很简单的样子哎

我们把所有的ai加起来,再用最晚的bi减去Σai不就是答案了???

这当然是错的,(不然给你bi干嘛)不过这么整还是有60分的(数据水qwq)

我们举个简单的例子

a1=1,b1=2

a2=2,b2=1000

显然你不可能在997秒时去送,因为第一个桶要求在第2秒送到,此时最晚在1秒后就必须去送了

那我们怎么做呢?

读入数据后,先按bi从小到大排序,因为要求时间越早的桶就越先送。

再将当前所有的ai加起来,这是当前送桶用的总时间sum。用当前的bi减sum,这是对于i桶来说,桶哥能休息的最大时间c。从所有c中找出最小值,就是答案。因为桶哥不能耽误任何一个桶,如果不选最小值,肯定会耽误一些桶。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
long long n,c[1000005],sum,minn=10000000001;
struct t{
    long long a,b;
}tong[1000005];
bool cmp(t k,t q)
{ 
   return k.b<q.b;
}
int main()
{
    scanf("%lld",&n);
    for(long long i=1;i<=n;i++)
    {scanf("%lld%lld",&tong[i].a,&tong[i].b);
    }
    sort(tong+1,tong+1+n,cmp);
    for(long long i=1;i<=n;i++)
    { sum+=tong[i].a;
     c[i]=tong[i].b-sum;
     if(c[i]<minn)minn=c[i];//其实等价于minn=min(minn,c[i]),而且c[i]好像可以直接写成c的样子
    }
    printf("%lld",minn);
}

T3:吃桶

扯点题外话

在吃完桶的一个小时内,我知道推荐生凉了

然后尝试十几天复习所有中考的内容

回归正题

看这个数据范围,显然又是一道数学题

我们把式子化简一下

x+y=z-2y

z-x=3y

咦看到这里我们好像有点思路了

既然z-x是3的倍数,那我们不妨枚举y,x算出z

骗到部分分(大佬都有40,就我只有10TAT)

不过z-x=3y好像可以继续挖掘的样子

我们可以分为三组来取

简单说就是z ≡ x(mod 3)的x,z为同一组

我们回到套餐式子

(x+z)*(bx-bz)=x*bx-x*bz+z*bx-z*bz

如果在一组中,对于任意一个z来说,所有与z是同一种类的x都可以和z进行上面那个式子

所以将与z同一种类的x的和,x*bx的和,bx的和统计起来就非常有必要了

那我们不妨建三个数组,下标为当前的i所属的种类,更新xh(x的和),bxh(bx的和)xbx这三个数组,以便后面的用,同时把当前的i当作z,计算答案

小坑见代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
long long zbz,xbz,zbx,ans,n,m,a[1000005],b[1000005],xbx[100005],xh[100005],bxh[100005],xs[100005];
const long long mod=10007;
int main()
{   
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
    cin>>b[i];
    }
    for(int i=1;i<=n;i++)
     {
      cin>>a[i];
     }
   for(int j=1;j<=3;j++)     
    {
     for(long long i=j;i<=n;i+=3)
     {
      xbz=(b[i]*xh[a[i]]+mod)%mod;
      zbx=(i*bxh[a[i]]+mod)%mod;
      zbz=((i%mod)*(b[i]%mod)*(xs[a[i]]%mod)%mod+mod)%mod;
      ans=(ans+xbx[a[i]]-xbz+zbx-zbz+mod)%mod;//注意先算答案,再更新数组
      bxh[a[i]]=(bxh[a[i]]+b[i]+mod)%mod;//注意取模
      xs[a[i]]++;//当前a[i]种类的x出现的数量
      xh[a[i]]=(xh[a[i]]+i+mod)%mod;
      xbx[a[i]]=(xbx[a[i]]+(i%mod)*(b[i]%mod)%mod+mod)%mod;
     }
     memset(xs,0,sizeof(xs));//一定要记住memset
     memset(xh,0,sizeof(xh));
     memset(xbx,0,sizeof(xbx));
     memset(bxh,0,sizeof(bxh));
     zbz=0;zbx=0;xbz=0;
    }
    ans=(ans+mod)%mod;
     cout<<ans;
}
 

 弱化版:洛谷P2671求和

posted @ 2019-06-19 17:00  千载煜  阅读(193)  评论(0编辑  收藏  举报