《Original Sequence》

因为是正整数解所以不能高斯消元了。

然后一开始想的是枚举a【1】,然后想办法O(n)检查,但是这个O(n)检查就是想不出来。

然后二分复杂度确实满足,但是感觉上不满足二分性。

在一段仔细思考之后,发现,a[1]的大小会控制其他值的大小,那就可以在check之中满足二分性。

然后就可以二分了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1005;
const int M = 2e3 + 5;
const LL Mod = 2147483647;
#define pi acos(-1)
#define INF 1e9
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int n,s[N][N],ans,a[N];
int check(int x) {
    a[1] = x;
    for(int i = 2;i <= n;++i) {
        a[i] = s[1][i] - a[1];
        if(a[i] <= 0) return 1;
    }
    for(int i = 2;i <= n;++i) {
        for(int j = i + 1;j <= n;++j) {
            if(a[i] + a[j] > s[i][j]) return 2;
            if(a[i] + a[j] < s[i][j]) return 1;
        }
    }
    return 0;
}
int main()
{
    n = read();
    int mx = 0;
    for(int i = 1;i <= n;++i)
        for(int j = 1;j <= n;++j) {
            s[i][j] = read();
            if(i == 1) mx = max(mx,s[i][j]);
        }
    int L = 1,r = mx - 1;
    while(L <= r) {
        int mid = (L + r) >> 1;
        if(check(mid) == 1) r = mid - 1;
        if(check(mid) == 2) L = mid + 1;
        if(check(mid) == 0) {
            ans = mid;
            break;
        }
    }
    printf("%d ",ans);
    for(int i = 2;i <= n;++i) printf("%d%c",s[1][i] - ans,i == n ? '
' : ' ');
    system("pause");
    return 0;
}
/*
4 5 2 1
4
0 9 6 5
9 0 7 6
6 7 0 3
5 6 3 0
*/
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/14450784.html