zoukankan      html  css  js  c++  java
  • 洛谷 P3909 异或之积 题解

    原题链接

    本人看了其它解法,发现本人的解法还是 首创

    而且我的解法好像和 ( imes 6) 没什么关系 ……

    (如果没 ( imes 6),我没还不用算逆元)

    别人的思路呢,大都是从 ( imes 6) 想到三个数的全排列,然后交换顺序枚举。

    下面看我的方法。

    先抛开 ( imes 6).

    [sum_{i=1}^n sum_{j=i+1}^n sum_{k=j+1}^n a_i imes a_j imes a_k ]

    [= sum_{j=1}^n a_j imes (sum_{i=1}^{j-1} a_i imes sum_{k=j+1}^n a_k) ]

    你可能不太明白?但是,今天的推式子很短,你必须步步理解。

    实际上,这步是考虑中间数被计算的次数。对它前面的所有数之和和后面数之和,它都会被计算。

    根据 乘法原理 ,就可以得到。

    我们想到了前缀和:

    [s_i = sum_{j=1}^i a_j ]

    那么,显然:

    [= sum_{j=1}^n a_j imes s_{j-1} imes (s_n - s_j) ]

    直接枚举解决问题。

    时间复杂度: (O(n)).

    实际得分:(100pts).

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    inline ll read(){char ch=getchar();int f=1; while(!isdigit(ch)) {if(ch=='-')f=-f; ch=getchar();}
    ll x=0;while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
    
    const ll N=1e6+1;
    const int MOD=1e9+7;
    
    int n; ll a[N];
    ll f[N],s[N];
    //f[i]=a[i]*(s[n]-s[i])
    
    inline ll solve(ll x) {
    	return (x<0)?(x+MOD):x;
    }
    
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++) a[i]=read(),s[i]=(s[i-1]+a[i])%MOD;
    	for(int i=1;i<=n;i++) f[i]=((a[i]*solve(s[n]-s[i])%MOD)*(s[i-1]))%MOD;
    	ll ans=0;
    	for(int i=1;i<=n;i++) ans=(ans+f[i])%MOD;
    	// for(int i=1;i<=n;i++) printf("%d %lld
    ",i,f[i]);
    	printf("%lld
    ",(ans*6)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    Java 网络编程的一些概念
    Java多线程之线程池
    Java多线程之线程协作
    Java多线程之线程同步
    Java 线程的基本使用
    线程的概念
    在Java中使用RabbitMQ
    Java Web
    Java 集合
    RabbitMQ的下载、安装
  • 原文地址:https://www.cnblogs.com/bifanwen/p/12516355.html
Copyright © 2011-2022 走看看