hdu3854.Glorious Array

来源:互联网 发布:openwrt python 编辑:程序博客网 时间:2024/05/10 21:39

http://acm.hdu.edu.cn/showproblem.php?pid=3854

题意:定义dist(x, y) = (c[x] ^ c[y]) * min{a[k] | x <= k <= y } + (c[x] ^ c[y] ^ 1) * INF, 操作1, 询问有多有个二元组(x, y)满足dist(x,y) < K, 操作2, 令c[x] ^= 1;  // 1 <= x, y, <= n <= 10^5;

思路,把序列以(a[i] <= k) 的i作分割点分组,那么,任意两个不同在一组的且c[x] != c[y]的点满足条件。反过来,当且仅当同在一组且c[x] != c[y] 的点才不满足,那么维护每个组0,和1分别的个数和整个数列0,1分别的个数,答案相减即可,还蛮简单的。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define sqr(x) ((x) * (x))#define two(x) (1 << (x))#define Rep(i, s, n) for (int i = s; i < (n); ++i)#define X first#define Y secondtypedef long long LL;const int MAXN = 100010;const double eps = 1e-9;const int INF = 1000000000;int n, q, k;int a[MAXN], c[MAXN], fa[MAXN], c0[MAXN], c1[MAXN];LL tot;void init(){    memset(c0, 0, sizeof(c0));    memset(c1, 0, sizeof(c1));    scanf("%d%d%d", &n, &q, &k);    Rep(i, 1, n + 1) scanf("%d", &a[i]);    Rep(i, 1, n + 1) scanf("%d", &c[i]);    Rep(i, 1, n + 1) if (a[i] >= k)    {        if (i > 1 && a[i - 1] >= k) fa[i] = fa[i - 1];        else fa[i] = i;    }    Rep(i, 1, n + 1)    {        if (c[i]) ++c1[0]; else ++c0[0];        if (a[i] >= k)        {            if (c[i]) ++c1[fa[i]]; else ++c0[fa[i]];        }    }    tot = (LL)c0[0] * c1[0];    Rep(i, 1, n + 1) if (a[i] >= k && fa[i] == i)        tot -= (LL)c0[i] * c1[i];}void work(){    while (q--)    {        int cc;        scanf("%d", &cc);        if (cc)            printf("%lld\n", tot);        else        {            int x;            scanf("%d", &x);            c[x] ^= 1;            tot -= (LL)c0[0] * c1[0];            if (c[x] == 1)            {                --c0[0];                ++c1[0];            }            else            {                ++c0[0];                --c1[0];            }            tot += (LL)c0[0] * c1[0];            if (a[x] >= k)            {                tot += (LL)c0[fa[x]] * c1[fa[x]];                if (c[x] == 1)                {                    --c0[fa[x]];                    ++c1[fa[x]];                }                else                {                    --c1[fa[x]];                    ++c0[fa[x]];                }                tot -= (LL)c0[fa[x]] * c1[fa[x]];            }        }    }}int main(){    int T;    scanf("%d", &T);    while (T--)    {        init();        work();    }    return 0;}


原创粉丝点击