题意:
倒数第p个fudu的人会被禁掉,每个人最多fudu1次,
每一轮可以选择fudu或者不fudu。如果是倒数第p个fudu
的人,他会被禁掉并且不会得到任何数量的冰红茶,并且还需要-154
个冰红茶。
每个人都想最大化能够得到的冰红茶数量,
输出每个人最后得到的冰红茶的数量。
思路:
因为倒数第p个人会被禁掉,每个人最多fudu一次,
那么其实前面只有前面n%p个人才会fudu,得到相应
数量的冰红茶,因为如果不拿的话就拿不到了。
后面的不会fudu,全为0。
代码:
#include
using namespace std;
typedef long long ll;
const int N = 1010;
int n,p;
ll a[N][N];
int main(){
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%lld",&a[i][j]);
}
}
int i;
for(i=1;i<=n&&i<=n%p;i++) cout<
题意:
求出点x与其他所有顶点的lca的乘积的后缀0的个数。
思路:
后缀0的个数与2和5的个数有关,后缀0的个数应该是
min(num2,num5)。
先预处理出每个数字的因子2和5的个数。
代码:
#include
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int n,q,x,y;
vector e[N];
ll num2,num5,ans[N],son[N];
void dfs(int u,int fa){//求以u为根节点的子树的结点总数
//树形dp
son[u]=1ll;
for(auto v:e[u]){
if(v==fa) continue;
dfs(v,u);
son[u]+=son[v];
}
}
void work(int u,int fa){
ll n2=0,n5=0;
for(int k=u;k%2==0;) n2++,k/=2;
for(int k=u;k%5==0;) n5++,k/=5;
for(auto v:e[u]){
if(v==fa) continue;
num2+=1ll*(son[u]-son[v])*n2;
num5+=1ll*(son[u]-son[v])*n5;
work(v,u);
num2-=1ll*(son[u]-son[v])*n2;
num5-=1ll*(son[u]-son[v])*n5;
}
ans[u]=min(num2+son[u]*n2,num5+son[u]*n5);
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i