Educational Codeforces Round 48
Educational Codeforces Round 48
C.Vasya And The Mushrooms
思路很简单,走法有一个统一形式就是先上下走,然后到某个位置左右一个来回。然后就推一下,后边那段的递推式子,枚举改变走法的位置即可。看出做法之后发现要推个式子,于是跑去写D了。。。然后D一开始思路错了。。。凉啊
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define PII pair<int,int>
#define MP make_pair
#define fr first
#define sc second
#define mem(WM) memset(WM,0,sizeof(WM))
typedef long long ll;
typedef unsigned long long ull;
const int N = 3e5 + 7;
using namespace std;
int n;
ll a[N][2],b[N][2],sum[N][2],s[N],A[N][2],num[N][2];
int main() {
scanf("%d",&n);
rep(i,1,n)scanf("%I64d",&a[i][0]);
rep(i,1,n)scanf("%I64d",&a[i][1]);
rep(i,1,n) s[i] = s[i-1] + a[i][0]+a[i][1];
sum[n][0] = a[n][1];
sum[n][1] = a[n][0];
per(i,n-1,1) {
sum[i][0] = (s[n]-s[i]) + sum[i+1][0] + ((n-i+1)*2-1)*a[i][1];
sum[i][1] = (s[n]-s[i]) + sum[i+1][1] + ((n-i+1)*2-1)*a[i][0];
}
ll ans = sum[1][0];
int sy=0,cc=0;
rep(i,1,n) {
A[i][sy] = A[i-1][sy] + cc*a[i][sy];
num[i][sy] = cc;
sy^=1;++cc;
ans = max(ans,A[i][sy]);
A[i][sy] = A[i][sy^1] + cc*a[i][sy];
num[i][sy] = cc;
ans = max(ans,A[i][sy]);
++cc;
}
sy = 1;
rep(i,1,n) {
ll tmp = A[i][sy] + sum[i+1][sy] + (s[n] - s[i])*(num[i][sy]+1);
ans = max(ans,tmp);
sy^=1;
}
printf("%I64d\n",ans);
return 0;
}
D.Vasya And The Matrix
给定横纵的异或值,让你求一个符合条件的矩阵。拆位之后,通过一行一列控制异或值,再检查以下最后一列/行是否满足条件即可。
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
#define PII pair<int,int>
#define MP make_pair
#define fr first
#define sc second
#define mem(WM) memset(WM,0,sizeof(WM))
typedef long long ll;
typedef unsigned long long ull;
const int N = 1e5 + 7;
const ll mod = 1e9 + 7;
using namespace std;
int n, m;
ll mp[111][111],a[111],b[111],r[111],c[111];
ll ans[111][111];
int solve() {
rep(i,1,m-1) {
if(c[i]==0) rep(j,1,n) mp[j][i]=c[i];
else {
mp[1][i] = 1;
rep(j,2,n) mp[j][i]=0;
}
}
rep(i,1,n) {ll x=0;
rep(j,1,m-1) x^=mp[i][j];
if(x==r[i]) mp[i][m] = 0;
else mp[i][m] = 1;
}
ll x=0;
rep(i,1,n)x^=mp[i][m];
if(x==c[m]) return 1;
rep(i,1,n-1) {
if(!r[i]) rep(j,1,m) mp[i][j]=r[i];
else {
mp[i][1] = 1;
rep(j,2,m) mp[i][j] = 0;
}
}
rep(i,1,m){ll x=0;
rep(j,1,n-1)x^=mp[j][i];
if(x==c[i]) mp[n][i] = 0;
else mp[n][i] = 1;
}
x=0;
rep(i,1,m)x^=mp[n][i];
if(x==r[n]) return 1;
return -1;
}
int tmp[111];
int main() {
scanf("%d%d",&n,&m);
rep(i,1,n) scanf("%I64d",&a[i]);
rep(i,1,m) scanf("%I64d",&b[i]);
rep(x,0,30) {
rep(i,1,n) r[i] = !!(a[i]&(1<<x));
rep(i,1,m) c[i] = !!(b[i]&(1<<x));
int t = solve();
if(t == -1)
return puts("NO"),0;
rep(i,1,n)rep(j,1,m)
ans[i][j] += (mp[i][j]<<x);
}
puts("YES");
rep(i,1,n) {
rep(j,1,m) printf("%I64d ",ans[i][j]);puts("");
}
return 0;
}
E. Rest In The Shades
大概做法懂了,对每个询问的点它和下方的那个光源的轨迹会形成一个三角形,二分求x轴上两条边中间的覆盖区域即可。这个可以预处理前缀和。二分两个边界,两边要特判一下相交。然后相似三角形即可求出在轨迹上的投影。。。