zoukankan      html  css  js  c++  java
  • 痛苦的 01 矩阵(和式推导)

    【传送门】https://acm.ecnu.edu.cn/contest/113/problem/C/

    【题解】

     推导过程:

     

    【技巧】

    (1)直接用二维数组存储矩阵肯定超内存,注意到K的范围该矩阵是一个稀疏的矩阵所以直接将其转化为线性的,a[(i-1)+j]表示其第i行第j列的状况

    (2)注意到单个点的改动只能影响到十字形的局部,所以在每次求ans时可以利用上一次的ans加上这一次改动形成的差值(或者说叫贡献)。

    (3)一定要注意和式变换时无关项∑别轻易丢弃,也许它形成一个常数n的系数。

    (4)取模防止负数 ,先按常规方法取模算出x,最后调整x,x = (x + mod) % mod

    【AC代码】

    #include<iostream>
    #include<map>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+10;
    const ll mod = 1e9+7;
    ll c[maxn];
    ll r[maxn];
    ll total;
    map<ll,int> mp;
    ll n,k,q;
    
    int main(){
        ios::sync_with_stdio(false);
        while(cin>>n>>k>>q){
            ll ans = 0;
            total = n*n - k;//0的总数等于总数减去1的个数
             
            for(int i=1; i<=n; i++){
                c[i] = r[i] = n;
            } 
            mp.clear();
            
            int u, v;
            for(int i=1; i<=k; i++){
                cin>>u>>v;
                mp[(u-1)*n + v] = 1;
                r[u]--;//把1的个数全部减掉就是这一行的0的个数 
                c[v]--;
            }
            for(int i=1; i<=n; i++){
                ans+=r[i]*r[i] % mod;
                ans+=c[i]*c[i] % mod;
            }
            ans = ans % mod;
            ans = (n-2)*ans % mod;
            total = total%mod;
            ans += (2*total*total%mod + total) % mod;
            ans = ans%mod;
            cout<<ans<<endl;//第一次的ans 
            
            for(int i=1; i<=q; i++){
                cin>>u>>v;
                if(mp[(u-1)*n + v]){//如果这一位是1,则反转为0,  0的个数增加 
                    mp[(u-1)*n + v] = 0;
                    
                    ans = ( (ans + (n-2)*(2*r[u] + 2 + 2*c[v]) ) % mod + (4*total + 3) % mod ) % mod;
                    
                    r[u]++;
                    c[v]++;
                    total++;
                    
                }
                else{
                    mp[(u-1)*n + v] = 1;
                    ans = ( (ans + (n-2)*(-2*r[u] + 2 - 2*c[v]) + mod) % mod + (-4*total + 1) % mod ) % mod;
                    ans = (ans + mod)%mod;//防止ans是负数 
                    r[u]--;
                    c[v]--;
                    total--;
                }
                cout<<ans<<endl;
            }
        }
    }
  • 相关阅读:
    ubuntu--基础环境瞎搞集合
    java _tomcat_mysql 部署
    简单Dp----最长公共子序列,DAG最长路,简单区间DP等
    大素数判断和素因子分解(miller-rabin,Pollard_rho算法)
    ssh 命令
    linux服务器上设置多主机头,设置多web站点
    getline()函数
    SGU[118] Digital Root
    SGU[117] Counting
    SGU[104] Little shop of flowers
  • 原文地址:https://www.cnblogs.com/czsharecode/p/9740202.html
Copyright © 2011-2022 走看看