1. 程式人生 > >牛客國慶集訓派對Day4

牛客國慶集訓派對Day4

G - 區間權值

題目描述

小 Bo 有 n 個正整數 a1..an,以及一個權值序列 w1…wn,現在他定義 現在他想知道 的值,需要你來幫幫他 你只需要輸出答案對 109+7 取模後的值

輸入描述:

第一行一個正整數 n
第二行 n 個正整數 a1..an
第三行 n 個正整數 w1..wn

輸出描述:

輸出答案對 109+7 取模後的值

示例1

輸入

複製

3
1 1 1
1 1 1

輸出

複製

10

備註:

1≤ n≤ 3x 105
1≤ ai≤ 107
1≤ wi≤ 107

注意:取模的時候不要ans+=balabala%mod,這樣只是給等號後的數取模了,沒有給ans加後的值取模,會爆的嚶嚶嚶qwq

程式碼如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#define ll long long
using namespace std;
const int N=300005,mod=1e9+7;
ll sumA[N],sumB1[N],sumB[N],W[N],a[N];
int main(){
    int n;
    scanf("%d",&n);
    memset(sumA,0,sizeof(sumA));
    memset(sumB,0,sizeof(sumB));
    memset(sumB1,0,sizeof(sumB1));
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        sumA[i]=(sumA[i-1]+a[i])%mod;
    }
    for(int i=1;i<=n;i++){
        sumB[i]=(a[i]*i%mod+sumB[i-1])%mod;
        sumB1[i]=(a[n-i+1]*i%mod+sumB1[i-1])%mod;
    }
    for(int i=1;i<=n;i++){
        scanf("%lld",&W[i]);
    }
    ll tmp,ans;
    int k;
    if(n==1)ans=W[1]*a[1];
    else ans=(sumA[n]*W[1]%mod+sumA[n]*W[n]%mod)%mod;
    for(int r=2;r<n;r++){
        if(2*r-1<=n)k=r;
        else{
            k=min(r-1,n-r+1);
        }
        tmp=((sumB[k-1]+sumB1[k-1])%mod+((sumA[n-k+1]-sumA[k-1])+mod)%mod*k%mod)%mod;
        ans=(ans+tmp*W[r]%mod)%mod;
    }
    printf("%lld\n",ans);
}

I - 連通塊計數

題目描述

小 A 有一棵長的很奇怪的樹,他由 n 條鏈和 1 個點作為根構成,第 i 條鏈有 ai 個點,每一條鏈的一端都與根結點相連。 現在小 A 想知道,這棵長得奇怪的樹有多少非空的連通子樹,你只需要輸出答案對 998244353 取模的值即可

輸入描述:

第一行一個正整數 n
第二行 n 個正整數 a1…an

輸出描述:

輸出答案對 998244353 取模後的值

示例1

輸入

複製

2
1 1

輸出

複製

6

備註:

1≤ n≤ 105
1≤ ai≤ 107

思路:這是個思維題啊,還挺不錯的

當沒有根的時候:bi=(a[i]+1)*a[i]/2     把b1到bn加起來

當有根的時候(a[1]+1)*(a[2]+1)*…(a[n]+1)

不考慮根的情況好理解,當有根節點的時候,每一條鏈從根開始,一共有1,2,3…1+a[i]種情況,把每個鏈的情況乘起來就好啦~

程式碼如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#define ll long long
using namespace std;
const int N=300005,mod=998244353;

ll mod_pow(ll a,ll b){
    ll res=1;
    while(b){
        if(b&1)res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}

int main(){
    int n;
    ll a;
    scanf("%d",&n);
    ll res1=1,res2=0;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a);
        res2=(res2+a*(a+1)%mod*mod_pow(2,mod-2))%mod;
        res1=res1*(a+1)%mod;
    }
    printf("%lld\n",(res1+res2)%mod);
}