2021.11.16 测试

T1:寻找宝藏

对于原矩阵维护一个二维前缀和和后缀和,这样宝藏的数目就可以在两个点对上统计贡献,枚举其中一个点对,用 3*k个树状数组 寻找另一个点即可(本题的精髓,详见代码中//★★★  //*1)

*0:题意

绿色部分算作两次!

 

*1:(如上图)

//f[]:矩阵前缀和

//g[]:矩阵后缀和

S阴影 (即k)=(f[x1][y1]+g[x2][y2])-(g[x1+1][y1+1]+f[x2-1][y2-1])
=(f[x1][y1]-g[x1+1][y1+1])-(f[x2-1][y2-1]-g[x2][y2])

=f ' [x1][y1]-f ' [x2-1][y2-1]

=k

=>f ' [x2-1][y2-1]=f ' [x1][y1]-k

=>f ' (x2-1,y2-1)的对应值为f ' (x1,y1)-k

 

*2:

x1(i'),x2(i)∈[1,n]

y1(j'),y2(j)∈[1,m]

 

#include<bits/stdc++.h>
using namespace std;
char ch;
int res;
const int N=100003,M=103,K=100003;
inline int rd()
{
    while((ch=getchar())<'0'||'9'<ch);
    res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-'0';
    return res;
}
int n,m,k,cnt,f[N][M],g[N][M];
long long ans;
struct BIT
{
    int t[M];//树状数组  //★★★
    void update(int x)
    {
        for(;x<M;x+=(x&-x))t[x]++;
    }
    int query(int x)//★★★
    {
        int numm=0; 
        for (;x;x-=(x&-x))numm+=t[x];
        return numm;
    }
}s[K*3];
int main()
{
    n=rd(),m=rd(),k=rd();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            while((ch=getchar())^'.'&&ch^'$');
            f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
            if(ch^'.')f[i][j]++,g[i][j]++,cnt++;
        }
    }
    for(int i=n;i>=1;i--)
        for(int j=m;j>=1;j--)
            g[i][j]+=g[i+1][j]+g[i][j+1]-g[i+1][j+1];
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            f[i][j]-=g[i+1][j+1];//*1
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++) 
            s[f[i-1][j-1]+2*cnt].update(j);//*1&*2
        for(int j=1;j<=m;j++)
            ans+=s[f[i][j]-k+2*cnt].query(j);//*1&*2 //+2*cnt:防止下标为负报错 (cnt-f[i][j]) 与 (cnt-k)
    }
    cout<<ans;
}

 

T2:分身

f : 贡献的前缀和

fi=[fi-1+(ai+fi-1)/(n-1)]%mod

=[fi-1+(ai+fi-1)]*逆元(n-1)%mod

a[i]的值即为其后的值做出的总贡献,即(fn-fi)

 

#include<bits/stdc++.h>
#define int unsigned long long
using namespace std;
char ch;
int res;
inline int rd()
{
    while((ch=getchar())<'0'||'9'<ch);
    res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')res=(res<<1)+(res<<3)+ch-'0';
    return res;
}
const int mod=998244353;
int a[1000002];
int f[1000002];
int n,ans;
int quick_pow(int x,int y)
{
    ans=1;
    while(y)
    {
        if(y&1)ans=(ans*x)%mod;
        y>>=1;
        x=x*x%mod;
    }
    return ans;
}
int ny(int x){return quick_pow(x,mod-2);}
signed main()
{
    n=rd();
    int k=ny(n-1);
    for(int i=1;i<=n;i++)a[i]=rd();
    for(int i=1;i<=n;i++)
    {
        a[i]+=f[i-1];
        f[i]=k*(f[i-1]*(n-1)%mod+a[i])%mod;
    }
    for(int i=1;i<=n;i++)cout<<(f[n]+mod-f[i])%mod<<' ';
}

 

posted @ 2021-11-16 20:15  penggeng  阅读(38)  评论(0编辑  收藏  举报