刷了一下也没有时间补题,看了别人的题解,就总结一下:
A,签到
B,签到
D:没有dp出来待补(不知道哪里错了)
E:待补
F:只有log个除数,预处理前缀和,从小到大排序ai,处理logp(ai)。
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
using namespace std;
typedef long long int ll;
const ll mod = 1e9;
const int maxn = 500000;
int n,m;
int a[maxn+5];
int Div[31][maxn+1];
ll solve(ll p)
{
ll cost = 1, sum=0;
int f = ceil( log(a[1])/log(p) );
int f_ = ceil( log(a[n])/log(p) );
for(int i=1;i<=f;i++) cost*=p;
for(;f<=f_;f++,cost*=p)
{
int r = upper_bound(a+1,a+n+1,cost) - a -1;
int l = upper_bound(a+1,a+n+1,cost/p) - a;
if(l>n) break;
if(r>n) r=n;
sum = (sum + (Div[f][r] - Div[f][l-1] + mod)%mod )%mod;
}
return sum;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
ll ans = 0;
sort(a+1,a+n+1);
for(int i=1;i<=30;i++)
{
for(int j=1;j<=n;j++) Div[i][j] = (Div[i][j-1] + a[j]/i)%mod;
}
ll ANS = 0;
for(int i=1,p;i<=m;i++)
{
scanf("%d",&p);
ll S = solve(p);
ans = (ans + 1ll*i*S%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}
J:
题意:n个人,1代表男,0代表女,第i个人有i个宝物,现在要把人划分成G1,G2,G3,G4。G1,G2都是女,G3,G4都是男,
使得G1 + G3 的宝物对于 G2+G4的宝物数量。
分析:当 n*(n+1)/2 为奇数时肯定没有解,然后两个部分 数量都是 n*(n+1)/4,有点难解释,看代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<vector>
using namespace std;
typedef long long int ll;
const int maxn = 100000;
int n,m,ans[maxn+5],c[maxn+5];
char s[maxn+5];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%s",(s+1));
if((1ll*n*(n+1)/2)%2)
{
printf("-1\n");
continue;
}
ll sum = 1ll*n*(n+1)/4;
for(int i=n; i>=1; i--)
{
if(sum>=i) sum-=i,c[i] = 1;//分组 这样分肯定有解,
else c[i] = 0;
}
for(int i=1; i<=n; i++)
{
if(c[i])
{
if(s[i]=='1') ans[i] = 3;
else ans[i] = 1;
}
else
{
if(s[i]=='1') ans[i] = 4;
else ans[i] = 2;
}
}
for(int i=1;i<=n;i++) printf("%d",ans[i]);
printf("\n");
}
return 0;
}
K;没看懂
L:签到
M:签到