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
",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轴上两条边中间的覆盖区域即可。这个可以预处理前缀和。二分两个边界,两边要特判一下相交。然后相似三角形即可求出在轨迹上的投影。。。

原文地址:https://www.cnblogs.com/RRRR-wys/p/9417149.html