D1T1:与或和
对每位处理,问题变成所有内部不包含0/1的矩阵的个数,单调栈维护即可。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 5 using namespace std; 6 7 const int N=1010,mod=1e9+7; 8 int top,sum,sm,n,mx,a[N][N],b[N][N],st[N],sz[N],l[N][N]; 9 10 int work(int w,int op){ 11 rep(i,1,n) rep(j,1,n) 12 if((a[i][j]&(1<<w))) b[i][j]=op; else b[i][j]=op^1; 13 rep(i,1,n){ 14 l[i][n]=b[i][n]; 15 for(int j=n-1; j; j--) 16 if(!b[i][j]) l[i][j]=0; else l[i][j]=l[i][j+1]+1; 17 } 18 int tmp=0; 19 rep(j,1,n){ 20 top=0,sum=0; 21 rep(i,1,n){ 22 int now=0; 23 while (top && st[top]>=l[i][j]) 24 sum-=st[top]*sz[top],now+=sz[top],top--; 25 st[++top]=l[i][j]; sz[top]=now+1; 26 sum+=st[top]*sz[top]; tmp=(tmp+sum)%mod; 27 } 28 } 29 return tmp; 30 } 31 32 int main(){ 33 freopen("andorsum.in","r",stdin); 34 freopen("andorsum.out","w",stdout); 35 scanf("%d",&n); 36 rep(i,1,n) rep(j,1,n) scanf("%d",&a[i][j]),mx=max(mx,a[i][j]); 37 rep(i,1,n) rep(j,1,n) sm=(sm+1ll*i*j)%mod; 38 int ans1=0,ans2=0; 39 rep(w,0,32){ 40 if ((1ll<<w)>mx) break; 41 int t=(1ll<<w)%mod; 42 ans1=(ans1+1ll*t*work(w,1)%mod)%mod; 43 ans2=(ans2+1ll*t*(sm-work(w,0)+mod)%mod)%mod; 44 } 45 printf("%d %d\n",ans1,ans2); 46 return 0; 47 }