• 经典傻逼题


    Description

    这是一道经典傻逼题,对经典题很熟悉的人也不要激动,希望大家不要傻逼。
    考虑一张N个点的带权无向图,点的编号为1到N。 对于图中的任意一个点集(可以为空或者全集),所有恰好有一个端点在这个点集中的边组成的集合被称为割。 一个割的权值被定义为所有在这个割上的边的异或和。

    一开始这张图是空图,现在,考虑给这张无向图不断的加边,加入每条边之后,你都要求出当前权值最大的割的权值, 注意加入的边永远都不会消失。

    Input

    输入的第一行包括一个数ID表示数据编号, 如第一组数据中的ID = 1。注意样例数据中的ID = 0。
    接下来的第一行包括两个整数N,M表示图的点数和总共加的边。
    接下来M行,每行三个正整数x,y,w表示在点x和点y之间加入一条权值为w的边。
    注意x和y可能相同,两条不同的边也可能连接了同一对点。

    此外, w将以二进制形式从高位向低位给出,比如, 6 = 110(2),因此如果边
    权为 6,那么w将会是110。
    $1leq Nleq 500,1 leq M leq 1000$, $0 leq L leq 1000$, $1 leq x,y leq N$

    Output

    输出M行,按顺序输出每一条边加入之后权值最大的割的权值。
    同样,你也要以二进制形式输出,形式和输入格式中描述的形式一样。

    Sample Input

    1
    2
    3
    4
    5
    6
    7
    8
    0 3
    6
    1 2 1
    1 2 1
    3 3 111
    1 3 101101
    1 2 1011
    2 3 111011

    Sample Output

    1
    2
    3
    4
    1 0 0
    101101
    101101
    110000

    HINT

    前三条边加入之后的答案较为显然,考虑后三条边,加入第六条边之前, 考

    虑点集${1,2}$,它对应的割只有第四条边, 因此答案就是第四条边的权值,考虑加

    入最后一条边以后的情况,此时点集${1,2}$对应的割变成了第四条边和第六条边组

    成的集合,权值也发生了相应的改变。 点集${2}$对应的割是第五条边和第六条边

    组成的集合, 可以证明这就是权值最大的割,权值为$1011(2)$xor$111011(2) =110000(2)$

    Solution

    考虑这个”割”的限制貌似并不是很好做,把边放到点上,每次选出一些点集。对于一条边,如果一条边的两个端点都在选出的点集中,那么在异或中就会被抵消掉,相当于没有选。每次选择一个点,相当于选择了和它相连的所有边,这个点的权值就是和它相接的所有边的异或和。

    那么问题变成了每次选择一个点集,每个点有一个权值,使得选出的点的异或和做大。

    这样是一个裸的线性基模板题。但是每次暴力去跑复杂度为$O(mnl^2)$显然不对。

    然后那个异或可以bitset搞一下就是$O(frac{mnl^2}{w})$,这样电脑跑的快就可以过了

    比较好理解的是一个线段树分治的离线做法。对于每个点的固定的一个权值,存在于图中的时间是一个连续的区间,对于$m$次修改,可以把这个权值打到线段树上面对应的$log$个节点上去,但这个时候并不下传,具体来说就是线段树上的每一个节点开一个std::vector存一下这个区间上的所有。

    那么现在线段树上每个点维护的是一个区间的bitset的集合,我们想知道答案就最后在线段树上dfs一下,访问每一个点的时候加入当前dfs的基中,到叶子节点的时候在基中取max就是答案。

    正解很短但是比较神仙,傻逼不太会,先坑着。

    PS: 由于本傻逼考场上没想到有bitset这个东西结果还手打了一个二进制高精度。(傻逼不仅啥都不会傻逼题就更不会了)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249

    using namespace std;
    #define IL inline
    IL int () {
    char ch = getchar(); int u = 0, f = 1;
    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
    while (isdigit(ch)) { u = (u << 1) + (u << 3) + ch - 48; ch = getchar(); }
    return u * f;
    }
    IL int read2() {
    char ch = getchar(); int u = 0, f = 1;
    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }
    while (isdigit(ch)) { u = (u << 1) + ch - 48; ch = getchar(); }
    return u * f;
    }
    #define rep(i, j, k) for (int i = j; i <= k; ++i)
    #define repd(i, j, k) for (int i = j; i >= k; --i)

    typedef long long ll;

    const int maxn = 1e5 + 10;
    int val[maxn], n, m, id, vis[maxn];
    int L;

    namespace BF {
    namespace subtask2 {
    class my2 {
    public:
    unsigned long long len[16]; int cd;
    my2() { memset(len, 0, sizeof len); cd = 0; }
    void init (char *a, int n) {
    cd = (n - 1) / 64;
    rep(i, 0, n - 1) len[(n - i - 1) / 64] |= (unsigned long long)(a[i] - '0') << ((n - i - 1) & 63);
    }
    void operator = (const my2 rhs) { memcpy(len,rhs.len,sizeof len); cd = rhs.cd; }
    void operator = (int x) {
    memset(len, 0, sizeof (len));
    cd = 0;
    }
    bool operator < (const my2 rhs) {
    if (cd != rhs.cd) return cd < rhs.cd;
    repd(i, cd, 0) if (len[i] != rhs.len[i]) return len[i] < rhs.len[i];
    return false;
    }
    my2 operator ^ (const my2 rhs) const {
    my2 rtn;
    rtn.cd = max(cd, rhs.cd);
    rep(i, 0, rtn.cd) rtn.len[i] = len[i] ^ rhs.len[i];
    while (rtn.cd && rtn.len[rtn.cd] == 0) rtn.cd--;
    return rtn;
    }
    void Xor (const my2 rhs) {
    cd = max(cd, rhs.cd);
    rep(i, 0, cd) len[i] = len[i] ^ rhs.len[i];
    while (cd && len[cd] == 0) cd--;
    }
    void p32(unsigned long long x,bool f1) {
    int b=1;
    repd(i, 63, 0) if(x&(1ull<<i))putchar 大专栏  经典傻逼题('1'),f1=1; else if(f1)putchar('0');
    }
    void print() {
    if (cd == 0 && len[0] == 0) { puts("0"); return; }
    repd(i, cd, 0) p32(len[i],(i!=cd));
    printf("n");
    }
    void update(const my2 rhs) {
    int nw=max(cd,rhs.cd);
    repd(i, nw, 0) if(len[i]&&rhs.len[i]) return;
    else if(!len[i]&&rhs.len[i]) break;
    cd=max(cd,rhs.cd);
    repd(i,cd,0) len[i]=len[i]^rhs.len[i];
    }
    }val[505];
    namespace LineBase {
    my2 a[1005];
    int main(my2 *b, int n) {
    rep(i, 0, min(L * 64,1000)) a[i] = 0;
    rep (i, 1, n) {
    if(!b[i].cd&&b[i].len[0]==0)continue;
    my2 tmp = b[i];
    repd (j, tmp.cd, 0) {
    repd(bi, 63, 0) {
    if (tmp.len[j]>>bi&1ull) {
    if (a[(j<<6)|bi].cd == 0 && a[(j<<6)|bi].len[0] == 0) a[(j<<6)|bi] = tmp;
    tmp.Xor(a[(j<<6)|bi]);
    }
    }
    }
    }
    my2 ans; ans = 0;
    repd (j, min(L * 64,1000), 0) {
    if (ans < (ans ^ a[j])) ans.Xor(a[j]);
    } ans.print();
    return 0;
    }
    int ins(int i,int P) {
    my2 tmp = val[i];
    repd (j, tmp.cd, 0) {
    repd(bi, 63, 0) {
    if (tmp.len[j]>>bi&1ull) {
    if (a[(j<<6)|bi].cd == 0 && a[(j<<6)|bi].len[0] == 0) a[(j<<6)|bi] = tmp;
    tmp.Xor(a[(j<<6)|bi]);
    }
    }
    }
    my2 ans; ans = 0;
    repd (j, min(L * 64,1000), 0) {
    if (ans < (ans ^ a[j])) ans.Xor(a[j]);

    } if(P) ans.print();
    }
    }
    char temp[1005];
    IL void work() {
    rep(i, 1, m) {
    int x = read(), y = read();
    scanf("%s", temp); int lent = strlen(temp);
    my2 qwq;
    qwq.init(temp, lent);
    val[x].Xor(qwq);
    val[y].Xor(qwq);
    // cerr<<"---n";
    // val[x].print(); val[y].print();
    if (id != 4 && id != 5) LineBase::main(val, n);
    else LineBase::ins(x,0),LineBase::ins(y,1);
    }
    }
    }
    }

    namespace SEG {
    const int maxn = 1005;
    class my2 {
    public:
    unsigned long long len[16]; int cd;
    my2() { memset(len, 0, sizeof len); cd = 0; }
    void init (char *a, int n) {
    cd = (n - 1) / 64;
    rep(i, 0, n - 1) len[(n - i - 1) / 64] |= (unsigned long long)(a[i] - '0') << ((n - i - 1) & 63);
    }
    void operator = (const my2 rhs) { memcpy(len,rhs.len,sizeof len); cd = rhs.cd; }
    void operator = (int x) {
    memset(len, 0, sizeof (len));
    cd = 0;
    }
    bool operator < (const my2 rhs) {
    if (cd != rhs.cd) return cd < rhs.cd;
    repd(i, cd, 0) if (len[i] != rhs.len[i]) return len[i] < rhs.len[i];
    return false;
    }
    my2 operator ^ (const my2 rhs) const {
    my2 rtn;
    rtn.cd = max(cd, rhs.cd);
    rep(i, 0, rtn.cd) rtn.len[i] = len[i] ^ rhs.len[i];
    while (rtn.cd && rtn.len[rtn.cd] == 0) rtn.cd--;
    return rtn;
    }
    void Xor (const my2 rhs) {
    cd = max(cd, rhs.cd);
    rep(i, 0, cd) len[i] = len[i] ^ rhs.len[i];
    while (cd && len[cd] == 0) cd--;
    }
    void p64(unsigned long long x,bool f1) {
    int b=1;
    repd(i, 63, 0) if(x&(1ull<<i))putchar('1'),f1=1; else if(f1)putchar('0');
    }
    void print() {
    if (cd == 0 && len[0] == 0) { puts("0"); return; }
    repd(i, cd, 0) p64(len[i],(i!=cd));
    printf("n");
    }
    IL bool count() { return (cd || len[0]); }
    void update(const my2 rhs) {
    int nw=max(cd,rhs.cd);
    repd(i, nw, 0) if(len[i]&&rhs.len[i]) return;
    else if(!len[i]&&rhs.len[i]) break;
    cd=max(cd,rhs.cd);
    repd(i,cd,0) len[i]=len[i]^rhs.len[i];
    }
    }val[505];
    class Lb {
    public:
    my2 a[1005];
    void push_back(my2 inx) {
    repd (j, inx.cd, 0) {
    repd(bi, 63, 0) {
    if (inx.len[j]>>bi&1ull) {
    if (a[(j<<6)|bi].cd == 0 && a[(j<<6)|bi].len[0] == 0) a[(j<<6)|bi] = inx;
    inx.Xor(a[(j<<6)|bi]);
    }
    }
    }
    }
    my2 queryMax() {
    my2 ans; ans = 0;
    repd (j, min(1000,L*64), 0) if (ans < (ans ^ a[j])) ans.Xor(a[j]);
    return ans;
    }
    };

    vector<my2>sgt[maxn << 2];
    char s[maxn]; int lst[maxn];
    #define ls (p << 1)
    #define rs (p << 1 | 1)
    void modify(int p, int x, int y, int l, int r, my2 qwq) {
    if (x == l && y == r) {
    sgt[p].push_back(qwq);
    return;
    } int mid = (x + y) >> 1;
    if (r <= mid) modify(ls, x, mid, l, r, qwq);
    else if (l > mid) modify(rs, mid + 1, y, l, r, qwq);
    else modify(ls, x, mid, l, mid, qwq), modify(rs, mid + 1, y, mid + 1, r, qwq);
    }
    void dfs(int p, Lb &cur, int x, int y) {
    Lb temp = cur;
    for (int i = 0; i < sgt[p].size(); ++i) {
    temp.push_back(sgt[p][i]);
    }
    if (x == y) temp.queryMax().print();
    else dfs(ls, temp, x, (x + y) >> 1), dfs(rs, temp, ((x + y) >> 1) + 1, y);
    }
    IL void work() {
    rep(i, 1, m) {
    int x = read(), y = read();
    scanf("%s", s);
    my2 qwq;
    qwq.init(s, strlen(s));
    if (lst[x]) modify(1, 1, m, lst[x], i - 1, val[x]);
    if (lst[y]) modify(1, 1, m, lst[y], i - 1, val[y]);
    val[y].Xor(qwq); val[x].Xor(qwq);
    lst[x] = lst[y] = i;
    }
    rep(i, 1, n) if (lst[i]) { modify(1, 1, m, lst[i], m, val[i]); }
    Lb temp;
    dfs(1, temp, 1, m);
    }
    }

    int Lp[20] = {1000, 32, 32, 100, 1000, 1000, 300, 300, 1000, 1000, 1000};
    int main() {
    // freopen("shabiti.in", "r", stdin);
    // freopen("shabiti.out", "w", stdout);
    id = read();
    L = Lp[id] + 3; L /= 64; L++;
    n = read(), m = read();
    //BF::subtask2::work();
    SEG::work();
    return 0;
    }
  • 相关阅读:
    python语法基础-常用模块-re模块
    python语法基础-常用模块-长期维护
    python语法基础-函数-内置函数和匿名函数-长期维护
    python语法基础-函数-递归函数-长期维护
    python语法基础-函数-迭代器和生成器-长期维护
    python语法基础-函数-装饰器-长期维护
    python语法基础-函数-进阶-长期维护
    python语法基础-函数-基础-长期维护
    Python之路--目录
    mysql数据库-索引-长期维护
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12041180.html
Copyright © 2020-2023  润新知