A.K-Periodic Array
对K取模相同的位置的1和2进行统计,答案累加相对较小的那个数。
B.Fox Dividing Cheese
求最大公约数后,看两个数是否是通过除以2,3,5得到的这个公约数,是的话输出除的总次数,不是的话输出-1
C.Hamburgers
二分列举总的个数,然后验证这个个数能不能构成。
D.Vessels
对于某个区间,如果这个区间的总容量小于你要放进去的水的体积,那么,这段区间的所有船都会装满,也就是容量变为0,。
于是我们在添加的时候,就可以二分右端点,找到刚好(指的是再少一个就装不下了,而不是刚好装满)某段区间能容下放进去的水的体积,假如是在r处,则当前放进去的水的位置到r-1都会变成满的,也就是容量变为0,而r处的船的容量会变成,这段容量的和减去放进去的水的体积。特殊处理的是,如果从当前船到最后一个船的容量都不够,那么这段区间的所有船的容量全部变为0.
这道题用树状数组最好做,不过不会写树状数组的更新区间的log算法,于是写的线段树。
C题代码:
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
#define inf 1000000000002ll
string s;
long long int box[4];
long long int cost[4];
long long int aox[4];
long long int n;
bool pd[4];
int main()
{
cin>>s;
for(int i=1;i<=3;i++) cin>>box[i];
for(int i=1;i<=3;i++) cin>>cost[i];
cin>>n;
for(int i=0;i<s.size();i++)
{
if(s[i]=='B')
aox[1]++;
else if(s[i]=='S')
aox[2]++;
else if(s[i]=='C')
aox[3]++;
}
long long int ll=0;long long int rr=10000000000000ll;
long long int mid;
long long int d=0;
long long int ans=0;
while(ll<=rr)
{
mid=(ll+rr)/2;
d=0;
for(int i=1;i<=3;i++)
{
if(mid*aox[i]>box[i])
{
d+=(mid*aox[i]-box[i])*cost[i];
}
}
if(d>n)
rr=mid-1;
else
{
ans=mid;
if(ll!=mid) ll=mid;
else ll=mid+1;
}
}
cout<<ans<<endl;
return 0;
}
D题代码
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
#define inf 1000000000002ll
struct hammer
{
int right,left;
int lazy;
long long int sum;
}box[800401];
int aox[200001];
int n;
long long int kk;
void build(int now,int l,int r)
{
box[now].left=l;box[now].right=r;
if(r==l)
{box[now].sum=aox[l];box[now].lazy=1;}
else
{
int k=(r+l)/2;
build(now*2,l,k);
build(now*2+1,k+1,r);
box[now].sum=box[now*2].sum+box[now*2+1].sum;
box[now].lazy=1;
}
}
void pushdown(int a)
{
if(box[2*a].lazy==1)
box[2*a].lazy=0;
box[2*a].sum=0;
if(box[2*a+1].lazy==1)
box[2*a+1].lazy=0;
box[2*a+1].sum=0;
}
void update(int a,int l,int r,int b)
{
if(box[a].lazy==0)
{
box[a].lazy=-1;
if(box[a].left!=box[a].right)
pushdown(a);
}
if(box[a].left==l && box[a].right==r)
{
if(b==0)
{
if(box[a].lazy==1)
box[a].lazy=0;
box[a].sum=0;
}
else
{
box[a].sum=b;
}
}
else
{
int k=(box[a].right+box[a].left)/2;
if(k<l)
{
update(a*2+1,l,r,b);
box[a].sum=box[a*2].sum+box[a*2+1].sum;
}
else if(k>=r)
{
update(a*2,l,r,b);
box[a].sum=box[a*2].sum+box[a*2+1].sum;
}
else
{
update(a*2,l,k,b);
update(a*2+1,k+1,r,b);
box[a].sum=box[a*2].sum+box[a*2+1].sum;
}
}
}
void qury(int a,int l,int r)
{
if(box[a].lazy==0)
{
box[a].lazy=-1;
if(box[a].left!=box[a].right)
pushdown(a);
}
if(box[a].left==l && box[a].right==r)
{
kk+=box[a].sum;
}
else
{
int k=(box[a].right+box[a].left)/2;
if(k<l)
{
qury(a*2+1,l,r);
}
else if(k>=r)
{
qury(a*2,l,r);
}
else
{
qury(a*2,l,k);
qury(a*2+1,k+1,r);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&aox[i]);
build(1,1,n);
int q;
cin>>q;
for(int i=1;i<=q;i++)
{
int a;
scanf("%d",&a);
if(a==1)
{
int b,c;
scanf("%d%d",&b,&c);
kk=0;
qury(1,b,b);
if(kk>=c)
{
update(1,b,b,kk-c);
}
else
{
int ll=b;int rr=n;int ans=-1;
int mid;
while(ll<=rr)
{
mid=(ll+rr)/2;
kk=0;
qury(1,b,mid);
if(kk<c)
ll=mid+1;
else
{
ans=mid;
if(rr!=mid) rr=mid;
else rr=mid-1;
}
}
if(ans==-1)
update(1,b,n,0);
else
{
kk=0;
qury(1,b,ans);
update(1,b,ans-1,0);
update(1,ans,ans,kk-c);
}
}
}
else
{
int b;
scanf("%d",&b);
kk=0;
qury(1,b,b);
cout<<aox[b]-kk<<endl;
}
}
return 0;
}