Round 14:
Problem C:
Test instructions: n*m (01) matrix, N,m<=1e3. The maximum contains all 1 sub-rectangles and it is surrounded by 0 (the perimeter must be 0).
Drawing a few examples can be found that any legal full 1 sub-rectangles are formed a full ' 1 ' unicom component.
DFS searches all 1 of the Unicom components and records the top left and bottom right positions. Cannot fall on the border.
In the row/column prefix to determine whether the upper left and right next lap is 0, the two-dimensional prefix and determine whether the found sub-rectangles are all 1.
#include <bits/stdc++.h> using namespace std;
typedef long Long LL;
const int n=2e3+20,inf=0x3f3f3f3f;
const LL MOD=1E9+7;
int n,m,vis[n][n],r[n][n],c[n][n],a[n][n],f[n][n];
int Lef,rig,up,dow;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
void Dfs (int x,int y) {vis[x][y]=1;
Rig=max (Rig,y), Lef=min (lef,y);
Up=min (up,x), Dow=max (dow,x);
for (int i=0;i<4;i++) {int c=x+dx[i],d=y+dy[i]; if (c>=1&&c<=n&&d>=1&&d<=m&&!vis[c][d] &&a[c][d]==1) DFS (C,D)
;
}} bool Check () {int x1=up,y1=lef,x2=dow,y2=rig;
BOOL Flag=true;
cout<<x1<< ' <<y1<< ' <<x2<< ' <<y2<<endl;
int num= (rig-lef+1) * (dow-up+1);
int act=f[x2][y2]-f[x2][y1-1]-f[x1-1][y2]+f[x1-1][y1-1];
if (num!=act) Flag=false;
cout<<num<< ' <<act<<endl;
X1--, y1--, x2++,y2++;
int r0=y2-y1+1,c0=x2-x1+1;
int r1=r[x1][y2]-r[x1][y1-1],r2=r[x2][y2]-r[x2][y1-1]; int C1=c[y1][x2]-c[y1][x1-1],c2=c[y2][X2]-c[y2][x1-1];
cout<<r0<< ' <<c0<<endl;
cout<<r1<< ' <<r2<<endl;
cout<<c1<< ' <<c2<<endl; if (r1!=r0| |
R2!=R0) Flag=false; if (c1!=c0| |
C2!=C0) Flag=false; if (x1<=0| | x2>n| | y1<=0| |
Y2>M) Flag=false;
return flag;
} int main () {cin>>n>>m;
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf ("%d", &a[i][j]), r[i][j]=r[i][j-1]+ (a[i][j]==0);
for (int. j=1;j<=m;j++) for (int i=1;i<=n;i++) c[j][i]=c[j][i-1]+ (a[i][j]==0);
for (int. i=1;i<=n;i++) for (int j=1;j<=m;j++) f[i][j]=a[i][j]+f[i][j-1]+f[i-1][j]-f[i-1][j-1];
int ans=-1;
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) {if (a[i][j]==1&&!vis[i][j]) {lef=up=inf;
rig=dow=0;
DFS (I,J);
if (check ()) Ans=max (ans, (rig-lef+1) * (dow-up+1));
}} cout<<ans<<endl;
return 0; }
Problem D
Test instructions: Gives the sequence c of length n, and the sum of all intervals between [A, b] and n<=1e5,c[i]<=1e9.
The summation of XOR sum and one of the routines is to calculate the sum of each contribution by the binary.
That is, the total contribution of the B-bit is num * (1<<B), which is the number of intervals in which the difference or sum of the B-bit is 1.
After the current bit B is fixed, the value of the prefix B-bit XOR is processed.
Now enumerate right Endpoint J, then the left endpoint is between [j-b+1,j-a+1].
If the prefix J B-bit XOR is 0, you need to know the prefix [j-b,j-a] The number of B-bit XOR 1, using CNT[0/1] to record the interval.
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2E5+20;
const LL MOD=1E9+7;
ll N,c[n],a,b;
ll Pre[n];
int main ()
{
cin>>n>>a>>b;
for (int i=1;i<=n;i++)
scanf ("%lld", &c[i]);
ll Ans=0;
pre[0]=0;
for (int bit=0;bit<=30;bit++)
{
int cnt[2]={0,0};
for (int i=1;i<=n;i++)
{
pre[i]=pre[i-1]^ ((c[i]>>bit) &1);
if (i-b-1>=0)
Cnt[pre[i-b-1]]--;//del Old Time
if (i-a>=0)
cnt[pre[i-a]]++;//add new
ans= (ans+cnt[pre[i]^1]* (1ll<<bit))%mod;
}
}
cout<<ans<<endl;
return 0;
Problem E:
Test instructions: How many n nodes are there in the orederd tree with a diameter of <=m? n,m<=300.
Ordered tree: Nodes are numbered from left to right, and if two trees have edges and their end numbers are different, the two trees are different.
The height of the two subtrees connected with the <=m of the diameter is <=m by the addition of 1.
DP[I][J] is a node of I, the number of order tree with a height of j (note the diameter to be <=m when transferring).
Because the tree is ordered. Therefore, the state is shifted by the height of the subtree to which the root is first connected.
DP[I][J]
Root has only one subtree, dp[i][j]+=dp[i-1][j-1].
The root has several subtrees:
The height of the first subtree is j-1, which enumerates its size k, then dp[i][j]+=dp[k][j-1]*dp[i-k][x] (X=1...min (J,M-J)).
The first subtree height is J ', and the size is K, then the remaining portion height is j,dp[i][j]+=dp[k][j ']*dp[i-k][j] (j ' =1..min (j-2,m-j-1))
Direct computing Time complexity is O (n^4)
Because the DP time J ' and X are accumulated from a value to a certain value, the thought of using prefix and SUM[I][J]=DP[I][1..J] to optimize a bit can get O (n^3).
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=3E2+20;
int n,m;
ll mod,dp[n][n],sum[n][n];//sum[i][j]= dp[i][1]+dp[i][2]+. DP[I][J].
int main ()
{
cin>>n>>m>>mod;
Dp[1][0]=1;
for (int j=0;j<=m;j++)
sum[1][j]=1;
for (int i=2;i<=n;i++)
{for
(int j=1;j<=m;j++)
{
dp[i][j]= (dp[i][j]+dp[i-1][j-1])%mod;
for (int k=1;k<=i-2;k++)
{
//dp[i][j]+=dp[k][j-1]*dp[i-k][x],x=[1..min (j,m-j)].
int x=min (J,M-J);
Dp[i][j]= (dp[i][j]+ (dp[k][j-1]*sum[i-k][x])%mod)%mod;
DP[I][J]+=DP[K][X]*DP[I-K][J], X=[1..min (j-2,m-j-1)]
x=min (j-2,m-j-1);
Dp[i][j]= (dp[i][j]+ (dp[i-k][j]*sum[k][x])%mod)%mod;
}
Sum[i][j]= (Sum[i][j-1]+dp[i][j])%mod;
}
cout<<sum[n][m]<<endl;
return 0;