我是靠谱客的博主 欢呼龙猫,这篇文章主要介绍ECNU 2018.10 月赛 C(数学统计),现在分享给大家,希望可以做个参考。

原题: https://acm.ecnu.edu.cn/contest/113/problem/C/

题意:

01矩阵, C o s t ( i , j ) Cost(i,j) Cost(i,j)为i行和j列的0的个数, S u m = ∑ i = 1 n ∑ j = 1 n C o s t ( i , j ) Sum=sum_{i=1}^nsum_{j=1}^nCost(i,j) Sum=i=1nj=1nCost(i,j)
每次操作为反转一个位置的数,求开始的Sum和每次操作后的Sum

解析:

R i R_i Ri为i行的0数量, C j C_j Cj为j列的0数量, B i j B_{ij} Bij表示ij位置是否为0, A A A为矩阵中0的数量
∑ i = 1 n B i j = C j , ∑ j = 1 n B i j = R i , ∑ i = 1 n C j = ∑ j = 1 n R i = A sum_{i=1}^nB_{ij}=C_j,sum_{j=1}^nB_{ij}=R_i,sum_{i=1}^nC_{j}=sum_{j=1}^nR_{i}=A i=1nBij=Cj,j=1nBij=Ri,i=1nCj=j=1nRi=A
那么接下来化简题目表达式:
S u m = ∑ i = 1 n ∑ j = 1 n C o s t 2 ( i , j ) = ∑ i = 1 n ∑ j = 1 n ( R i + C j − B i j ) 2 = ∑ i = 1 n [ ( R i + C 1 − B i 1 ) 2 + … ( R i + C n − B i n ) 2 ] = ∑ i = 1 n [ ( R i + C 1 ) 2 + B i 1 − 2 B i 1 ( R i + C 1 ) + …   ] = ∑ i = 1 n [ ( n R i 2 + ( C 1 2 + … C n 2 ) + 2 R i A ) + R i − 2 R i 2 − ∑ j = 1 n 2 B i j C j ] Sum=sum_{i=1}^nsum_{j=1}^nCost^2(i,j)\=sum_{i=1}^nsum_{j=1}^n(R_i+C_j-B_{ij})^2\=sum_{i=1}^n[(R_i+C_1-B_{i1})^2+dots(R_i+C_n-B_{in})^2]\=sum_{i=1}^n[(R_i+C_1)^2+B_{i1}-2B_{i1}(R_i+C_1)+dots]\=sum_{i=1}^n[(nR_i^2+(C_1^2+dots C_n^2)+2R_iA)+R_i-2R_i^2-sum_{j=1}^n2B_{ij}C_j] Sum=i=1nj=1nCost2(i,j)=i=1nj=1n(Ri+CjBij)2=i=1n[(Ri+C1Bi1)2+(Ri+CnBin)2]=i=1n[(Ri+C1)2+Bi12Bi1(Ri+C1)+]=i=1n[(nRi2+(C12+Cn2)+2RiA)+Ri2Ri2j=1n2BijCj]
= ( n − 2 ) ∑ i = 1 n R i 2 + n ∑ j = 1 n C j 2 + 2 A 2 + A − 2 ∑ i = 1 n ∑ j = 1 n B i j C j = ( n − 2 ) ∑ i = 1 n R i 2 + ( n − 2 ) ∑ j = 1 n C j 2 + 2 A 2 + A =(n-2)sum_{i=1}^nR_i^2+nsum_{j=1}^nC_j^2+2A^2+A-2sum_{i=1}^nsum_{j=1}^nB_{ij}C_j\=(n-2)sum_{i=1}^nR_i^2+(n-2)sum_{j=1}^nC_j^2+2A^2+A =(n2)i=1nRi2+nj=1nCj2+2A2+A2i=1nj=1nBijCj=(n2)i=1nRi2+(n2)j=1nCj2+2A2+A

所以每次修改的时候找到原来的 R , C , A R,C,A R,C,A,再算出现在的比较计算就是答案。判断为1或0可以用set,注意每次操作后需要维护set。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5;
const LL mod=1e9+7;
LL a[N],b[N];

struct node{
    int x,y;
}e[N];
set<int>S[N];

int main(){
    LL n,k,q;
    scanf("%lld%lld%lld",&n,&k,&q);
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(int i=1;i<=k;i++){
        int x,y;scanf("%d%d",&x,&y);
        e[i].x=x,e[i].y=y;
        S[x].insert(y);
        a[y]++,b[x]++;
    }
    for(int i=1;i<=n;i++)a[i]=n-a[i],b[i]=n-b[i];//num of 0

    LL A=(n*n-k)%mod;
    LL All=(2*A*A+A)%mod;
    for(int i=1;i<=n;i++)All=(All+(n-2)*a[i]*a[i]%mod+(n-2)*b[i]*b[i]%mod)%mod;
    printf("%lldn",All);

    while(q--){
        int x,y;
        scanf("%d%d",&x,&y);

        LL pre=((n-2)*a[y]*a[y]%mod+(n-2)*b[x]*b[x]%mod+2*A*A%mod+A)%mod;
        LL now;
        if(S[x].find(y)==S[x].end()){//0->1
            now=((n-2)*(a[y]-1)%mod*(a[y]-1)%mod+(n-2)*(b[x]-1)%mod*(b[x]-1)%mod+2*(A-1)*(A-1)%mod+A-1)%mod;
            A--,a[y]--,b[x]--;
            S[x].insert(y);
        }
        else{
            now=((n-2)*(a[y]+1)%mod*(a[y]+1)%mod+(n-2)*(b[x]+1)%mod*(b[x]+1)%mod+2*(A+1)*(A+1)%mod+A+1)%mod;
            A++,a[y]++,b[x]++;
            S[x].erase(y);
        }
        All=((All+now-pre)%mod+mod)%mod;
        printf("%lldn",All);
    }
}

最后

以上就是欢呼龙猫最近收集整理的关于ECNU 2018.10 月赛 C(数学统计)的全部内容,更多相关ECNU内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(106)

评论列表共有 0 条评论

立即
投稿
返回
顶部