前言
比赛AK了(虽然是div2)
T1:
lcm不解释。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
LL gcd(LL a,LL b)
{
if(a==0) return b;
return gcd(b%a,a);
}
LL lcm(LL a,LL b) {return a/gcd(a,b)*b;}
int main()
{
LL a,b,c;scanf("%lld %lld %lld",&a,&b,&c);
printf("%lld",lcm(a,lcm(b,c)));
}
T2:
二分傻逼题,注意下边界。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#define LL long long
using namespace std;
const LL inf=1000000000000000000;
LL up(LL a,LL b) {return a%b==0?a/b:a/b+1;}
LL n,m,L;
LL h[200010],a[200010];
bool check(LL x)
{
LL tot=0;
for(int i=1;i<=n;i++)
{
if(up(inf,a[i])<=x) return true;
LL tmp=a[i]*x;
if(a[i]*x+h[i]<L) continue;
if(m-tot<=a[i]*x+h[i]) return true;
tot+=(a[i]*x+h[i]);
}
return false;
}
int main()
{
scanf("%lld %lld %lld",&n,&m,&L);
for(LL i=1;i<=n;i++) scanf("%lld",&h[i]);
for(LL i=1;i<=n;i++) scanf("%lld",&a[i]);
LL l=0,r=inf,ans;
while(l<=r)
{
LL mid=(l+r)/2;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%lld",ans);
}
T3:
显然dp。
f[i][j]
表示一串前i个,二串前j个的最大值。
好像不能转移,所以加一维0,1,2,分别表示最后都不是空格,一串空格结尾,二串空格结尾的最大值。(显然不存在都以空格结尾)。然后就可以转移了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define LL long long
using namespace std;
char s[3010],s1[3010];
LL map[3010][3010],A,B;
LL f[3010][3010][3];//0末尾都没空格,1一串有,2而串有
LL qs(char c)
{
if(c=='A') return 1;
if(c=='T') return 2;
if(c=='G') return 3;
if(c=='C') return 4;
}
int main()
{
scanf("%s %s",s+1,s1+1);
for(LL i=1;i<=4;i++)
for(LL j=1;j<=4;j++) scanf("%lld",&map[i][j]);
scanf("%lld %lld",&A,&B);
LL n=strlen(s+1),m=strlen(s1+1);
memset(f,-63,sizeof(f));
//f[0][0][1]=f[0][0][2]=(-(1LL<<60));
f[0][0][0]=0;
for(LL i=0;i<=n;i++)
for(LL j=0;j<=m;j++)
{
if(i+j==0) continue;
LL a=qs(s[i]),b=qs(s1[j]);
if(i!=0&&j!=0) f[i][j][0]=map[a][b]+max(f[i-1][j-1][0],max(f[i-1][j-1][1],f[i-1][j-1][2]));
if(j!=0) f[i][j][1]=max(f[i][j-1][0]-A,max(f[i][j-1][1]-B,f[i][j-1][2]-A));
if(i!=0) f[i][j][2]=max(f[i-1][j][0]-A,max(f[i-1][j][1]-A,f[i-1][j][2]-B));
}
printf("%lld\n",max(f[n][m][0],max(f[n][m][1],f[n][m][2])));
//printf("%lld %lld %lld",f[n][m][0],f[n][m][1],f[n][m][2]);
}
T4:
容易发现n没什么卵用……
因为对于没有钦定的地方,显然可以让b数组对应位置上都是0。
但是对于一段钦定位置前的位置,不一定填0优。
所以就按位考虑填0,1的代价,取较小值就可以了。
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
struct node{
int x,c;
}a[100010];
int n,m,c[2][35];
bool cmp(node a,node b) {return a.x<b.x;}
LL solve(int l,int r)
{
LL ans=0;int tmp=0;
if(a[l].x==1) for(int i=l;i<=r;i++) tmp^=a[i].c,ans+=(LL)tmp;
else
{
memset(c,0,sizeof(c));
for(int i=0;i<=30;i++)
{
for(int k=0;k<=1;k++)
{
int tmp=(k<<i);c[k][i]+=(tmp!=0);
for(int j=l;j<=r;j++)
tmp^=(a[j].c&(1<<i)),c[k][i]+=(tmp!=0);
}
ans+=(LL)(1<<i)*(LL)min(c[0][i],c[1][i]);
}
}
return ans;
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d %d",&a[i].x,&a[i].c);
sort(a+1,a+m+1,cmp);
int p=1;
LL ans=0;
while(p<=m)
{
int t=p;
while(p<m&&a[p].x+1==a[p+1].x) p++;
ans+=solve(t,p);
p++;
}
printf("%lld",ans);
}