玲珑学院OJ 1023 - Magic boy Bi Luo with his excited math problem 树状数组暴力

分析:a^b+2(a&b)=a+b  so->a^(-b)+2(a&(-b))=a-b

然后树状数组分类讨论即可

链接:http://www.ifrog.cc/acm/problem/1023

吐槽:这个题本来是mod(2^40),明显要用快速乘啊,但是用了以后狂T,不用反而过了,不懂出题人

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5+5;
const LL mod = (1ll<<40);
int T,n,m,a[N],b[N],p[N],cnt,kase;
LL c[4][N],sum[4];
inline void init()
{
    for(int i=0; i<4; ++i)
        for(int j=0;j<=cnt;++j)c[i][j]=0;
    sum[0]=sum[1]=sum[2]=sum[3]=0;
}
inline void up(LL &x,LL t)
{
    x+=t;
    if(x>=mod)x-=mod;
}
inline void add(int pos,int x,LL t)
{
    for(int i=x; i<=cnt; i+=i&(-i))up(c[pos][i],t);
}
inline LL ask(int pos,int x)
{
    LL ret=0;
    for(int i=x; i; i-=i&(-i))up(ret,c[pos][i]);
    return ret;
}
LL ksc(LL x,LL y)
{
    LL ret=0;
    while(y)
    {
        if(y&1)up(ret,x);
        y>>=1;
        up(x,x);
    }
    return ret;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; ++i)scanf("%d",&a[i]);
        for(int i=1; i<=m; ++i)scanf("%d",&b[i]),p[i]=b[i];
        sort(p+1,p+1+m);
        cnt = unique(p+1,p+1+m)-p-1;
        int ptr=1;
        LL ret=0;
        init();
        for(int i=1; i<=n; ++i)
        {
            int pos;
            for(; ptr<=m&&ptr<i; ++ptr)
            {
                pos = lower_bound(p+1,p+1+cnt,b[ptr])-p;
                add(0,pos,1);++sum[0];
                add(1,pos,ptr);up(sum[1],ptr);
                add(2,pos,b[ptr]);up(sum[2],b[ptr]);
                add(3,pos,1ll*b[ptr]*ptr%mod);up(sum[3],1ll*b[ptr]*ptr%mod);
            }
            /**j<i,b[j]<a[i]**/
            pos = lower_bound(p+1,p+1+cnt,a[i])-p;
            --pos;
            LL tmp =ask(0,pos);
            if(tmp!=0)
            {
                tmp = 1ll*i*a[i]%mod*tmp%mod;up(ret,tmp);
                //up(ret,ksc(1ll*i*a[i]%mod,tmp));
                tmp = -(ask(1,pos)*a[i]%mod);
                //tmp = -ksc(ask(1,pos),a[i]);
                up(tmp,mod);
                up(ret,tmp);
                tmp = -(ask(2,pos)*i%mod);
                //tmp = -ksc(ask(2,pos),i);
                up(tmp,mod);
                up(ret,tmp);
                up(ret,ask(3,pos));
            }
            /*********/
            /**j<i,b[j]>a[i]**/
            pos = upper_bound(p+1,p+1+cnt,a[i])-p;
            if(pos==cnt+1)continue;
            --pos;
            tmp = sum[0]-ask(0,pos);
            if(tmp==0)continue;
            tmp = -(1ll*i*a[i]%mod*tmp%mod);
            //tmp= -ksc(1ll*i*a[i]%mod,tmp);
            up(tmp,mod);
            up(ret,tmp);
            tmp = (sum[1]-ask(1,pos)+mod)%mod;
            tmp = tmp*a[i]%mod;
            //tmp = ksc(tmp,a[i]);
            up(ret,tmp);
            tmp = (sum[2]-ask(2,pos)+mod)%mod;
            tmp = tmp*i%mod;
            //tmp = ksc(tmp,i);
            up(ret,tmp);
            tmp = (sum[3]-ask(3,pos)+mod)%mod;
            tmp = (mod-tmp)%mod;
            up(ret,tmp);
            /*********/
        }
        init();
        ptr=m;
        for(int i=n; i; --i)
        {
            int pos;
            for(; ptr>i&&ptr; --ptr)
            {
                pos = lower_bound(p+1,p+1+cnt,b[ptr])-p;
                add(0,pos,1);++sum[0];
                add(1,pos,ptr);up(sum[1],ptr);
                add(2,pos,b[ptr]);up(sum[2],b[ptr]);
                add(3,pos,1ll*b[ptr]*ptr%mod);up(sum[3],1ll*b[ptr]*ptr%mod);
            }
            /**j>i,b[j]>a[i]**/
            pos = upper_bound(p+1,p+1+cnt,a[i])-p;
            --pos;
            if(pos!=cnt)
            {
                LL tmp = sum[0]-ask(0,pos);
                if(tmp!=0)
                {
                    tmp = 1ll*i*a[i]%mod*tmp%mod;up(ret,tmp);
                    //up(ret,ksc(1ll*i*a[i]%mod,tmp));
                    tmp = (sum[1]-ask(1,pos)+mod)%mod;
                    tmp = -(tmp*a[i]%mod);
                    //tmp = -ksc(tmp,a[i]);
                    up(tmp,mod);
                    up(ret,tmp);
                    tmp = (sum[2]-ask(2,pos)+mod)%mod;
                    tmp = -(tmp*i%mod);
                    //tmp = -ksc(tmp,i);
                    up(tmp,mod);
                    up(ret,tmp);
                    tmp = (sum[3]-ask(3,pos)+mod)%mod;
                    up(ret,tmp);
                }
            }
            /*********/
            /**j>i,b[j]<a[i]**/
            pos = lower_bound(p+1,p+1+cnt,a[i])-p;
            --pos;
            LL tmp = ask(0,pos);
            if(tmp==0)continue;
            tmp =-(1ll*i*a[i]%mod*tmp%mod);
            //tmp= -ksc(1ll*i*a[i]%mod,tmp);
            up(tmp,mod);
            up(ret,tmp);
            tmp = ask(1,pos);
            tmp = tmp*a[i]%mod;
            //tmp = ksc(tmp,a[i]);
            up(ret,tmp);
            tmp = ask(2,pos);
            tmp = tmp*i%mod;
            //tmp = ksc(tmp,i);
            up(ret,tmp);
            tmp = ask(3,pos);
            tmp = (mod-tmp)%mod;
            up(ret,tmp);
            /*********/
        }
        printf("Case #%d: %lld\n",++kase,ret);
    }
    return 0;
}

时间: 2024-10-29 19:06:15

玲珑学院OJ 1023 - Magic boy Bi Luo with his excited math problem 树状数组暴力的相关文章

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

2016中国大学生程序设计竞赛 - 网络选拔赛 C. Magic boy Bi Luo with his excited tree

Magic boy Bi Luo with his excited tree Problem Description Bi Luo is a magic boy, he also has a migic tree, the tree has N nodes , in each node , there is a treasure, it's value is V[i], and for each edge, there is a cost C[i], which means every time

树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree

1 // 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree 2 // 题意:n个点的树,每个节点有权值为正,只能用一次,每条边有负权,可以走多次,问从每个点出发的最大获益 3 // 思路: 4 // dp[i]: 从i点出发回到i点的最大值 5 // d[i][0] 从i点出发不回来的最大值 6 // d[i][1] 从i点出发取最大值的下一个点 7 // d[i][2] 从i点出发取次大值 8 // dfs1处理出这四个 9

HDU 5834 Magic boy Bi Luo with his excited tree

题目:Magic boy Bi Luo with his excited tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5834 题意:给一棵树,在树的每个结点可以收获一定的积分,每一条边会消耗一定的积分,每个结点积分取一次便完,但每次路过一条边,都会消耗积分,问从每一个结点出发,最多能捞多少积分.N范围10万,样例数1万. 思路: 不难的一道题,但细节较多,容易出错. 树形DP. 从i 点出发,大致可以分为向上 和 向下两种,先考虑向下的情

hdu5834 Magic boy Bi Luo with his excited tree(树形dp)

Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 723    Accepted Submission(s): 192 Problem Description Bi Luo is a magic boy, he also has a migic tree,

hdu 5834 Magic boy Bi Luo with his excited tree 树形dp+转移

Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1058    Accepted Submission(s): 308 Problem Description Bi Luo is a magic boy, he also has a migic tree,

Magic boy Bi Luo with his excited tree (树形dp)

Bi Luo is a magic boy, he also has a migic tree, the tree has NN nodes , in each node , there is a treasure, it's value is V[i]V[i], and for each edge, there is a cost C[i]C[i], which means every time you pass the edge ii , you need to pay C[i]C[i].

动态规划(树形DP):HDU 5834 Magic boy Bi Luo with his excited tree

非常难想的树形DP. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 const int N=100010; 6 int cnt,fir[N],nxt[N*2],to[N*2],val[N*2]; 7 int n,w[N],ans[N],fa[N],f1[N][2],f2[N][2]; 8 void addedge(int a,int b,in

【树形动规】HDU 5834 Magic boy Bi Luo with his excited tree

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5834 题目大意: 一棵N个点的有根树,每个节点有价值ci,每条树边有费用di,节点的值只能取一次,边权每次经过都要扣,问从每一个节点开始走最大能获得的价值. 题目思路: [树形动态规划] 首先用dfs求出从根1往下走的:节点u往下走最后回到节点u的最大值g[u],节点u往下走最后不回到u的最优值和次优值f[0][u],f[1][u] 接着考虑一个节点u,除了以上的情况还有可能是往它的父亲方向走,这