Massacre at Béziers+赤の夜

49 篇文章 0 订阅
39 篇文章 0 订阅

这里写图片描述
等差数列求和,算出多少个整周期。
二分或解方程

#include <cstdio>
#include <iostream>
#include <cmath>
#define ll unsigned long long
using namespace std;
ll n,t;
bool check(ll a,ll d1,ll mid)
{
    ll c=2;
    ll ans=a*mid+(((mid-1)*mid)/c)*d1;
    return ans<=t;
}
int main()
{
    freopen("sample.in","r",stdin);
    //freopen("sample.out","w",stdout);
    ll anse=0;
    scanf("%lld%lld",&n,&t);
    for(int i=1;i<=n;i++)
    {
        ll x,y,z;
        scanf("%lld%lld%lld",&x,&y,&z);
        if(x==0)
        {
            anse+=t;
            continue;
        } 
        /*if(y==0&&z==0)
        {
            continue;
        }*/
        ll l=0,r=t/x+y+1,ans=0;
        while(l<=r)
        {
            ll mid=(l+r)/2;
            if(check(x+y,z,mid)) l=mid+1,ans=mid;
            else r=mid-1;
        }
        ll c=2;
        ll ansx=(x+y)*ans+(((ans-1)*ans)/c)*z;
        if(ansx==t)
         anse+=y*ans+((ans-1)*(ans)/c)*z;
        else
        {
            anse+=y*ans+((ans-1)*(ans)/c)*z;
            if(t-ansx>x) anse+=(t-ansx-x);
            //printf("%lld\n",xxxx);
            //printf("%lld\n",ansy);
        }
        //printf("%lld\n",ansx);
    }
    printf("%lld",anse); 
    return 0;
}

这里写图片描述

暴力模拟
定义pushup x 数组为所以操作点对x答案的贡献
size[x]为x有多少儿子
son[x]表示x的子节点操作了几次
tag[x]表示x操作了几次


操作x,pushup[x]很明显要+size[x]+1
对于pushup[fat[x]]+=2(当前点+父亲点)
对pushup[fat[fat[x]]]++(x 的父节点)
tag[x]++
son[fat[x]]++
这次操作x对答案的贡献即为
1:pushup[x](本身影响 的点)
2:tag[fat[x]]*2(父节点的贡献)
3:tag[fat[fat[x]]](父节点的父节点的贡献)
4:temp+=son[fa[x]]-tagx

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
int n, m;
int fa[100010];
ll ans,tag[100010],pushup[100010],son[100010],size[100010];
ll read()
{
    ll res = 0;
    char ch = 0;
    while (ch < '0' || ch > '9')
        ch = getchar();
    while (ch >= '0' && ch <= '9')
    {
        res = res * 10 + ch - '0';
        ch = getchar();
    }
    return res;
}
int main()
{
    n=read();
    m=read();
    for (int  i=2;i<=n;i++)
    {
        fa[i]=read();
        size[i]++;
        size[fa[i]]++;
    }
    while (m--)
    {
        ll x;
        x=read();

        pushup[x] += size[x] + 1;
        pushup[fa[x]] += 2;
        pushup[fa[fa[x]]]++;

        tag[x]++;
        son[fa[x]]++;

        long long temp = pushup[x];
        temp+=tag[fa[x]]*2;
        temp+=tag[fa[fa[x]]];
        temp+=son[fa[x]]-tag[x];
        ans+=temp;
    }
    printf("%lld\n", ans);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值