hdu 4747 mex 線段樹 思維

2022-05-23 23:48:15 字數 2483 閱讀 4318

題意:我們定義mex(l,r)表示乙個序列a[l]....a[r]中沒有出現過得最小的非負整數, 然後我們給出乙個長度為n的序列,求他所有的連續的子串行的mex(l,r)的和。

思路:首先因為n的最大值就是2*10^5 所有我們字需要考慮200000之內的數就好了,然後o(2*n)可以求出(1,1),(1,2), (1,3),(1,4) ... (1,n)來 mex是不減的。

然後我們考慮將第乙個數拿走我們就能夠得到(2,2),(2,3) ......(2,n) , 如何求他們?下邊給出**:

下邊是貼上別人的,感覺有個例子很好理解。

例:         1, 6,0,2,3,1,4,3

初始mex 0,0,2,3,4,4,5,5       

mex[1,r]

刪除1後   0,  0,1,1,1,4,5,5

mex[2,r]

當刪除第乙個1後,紅色的mex不變!,紫色的mex值變為1,橙色的mex值不變,刪除點的mex置0

因此,用線段樹維護乙個單調不遞增佇列,每次求和。查詢位置時用二分。線段樹延時標記即可。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define cl(arr, val)    memset(arr, val, sizeof(arr))

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll __int64

#define l(x) (x) << 1

#define r(x) (x) << 1 | 1

#define mid(l, r) (l + r) >> 1

#define min(x, y) (x) < (y) ? (x) : (y)

#define max(x, y) (x) < (y) ? (y) : (x)

#define e(x) (1 << (x))

#define iabs(x) (x) < 0 ? -(x) : (x)

#define out(x) printf("%i64d\n", x)

#define keytree (chd[chd[root][1]][0])

#define read() freopen("din.txt", "r", stdin)

#define write() freopen("dout.txt", "w", stdout);

#define m 100007

#define n 200017

using namespace std;

int dx[4]=;

int dy[4]=;

const int inf = 0x7f7f7f7f;

const int mod = 1000000007;

const double eps = 1e-8;

int mex[n],a[n],next[n];

int vis[n];

ll val[4*n], lz[4*n];

int n;

void pushup(int rt)

void pushdown(int rt,int m)

}void build(int l, int r, int rt)

int m = (l + r) >> 1;

build(lc); build(rc);

pushup(rt);

}void update(int l, int r, ll sc, int l, int r, int rt)

pushdown(rt,r - l + 1);

int m = (l + r) >> 1;

if (l <= m) update(l,r,sc,lc);

if (r > m) update(l,r,sc,rc);

pushup(rt);

}ll query(int pos, int l,int r, int rt)

int bsr(int l, int r, int v)

else l = mid + 1;

}return ans;

}int main()

for (int i = 1; i <= n; ++i) if (!next[i]) next[i] = n + 1;

cl(vis,0); int last = 0;

for (int i = 1; i <= n; ++i)

last++;}}

build(1,n,1); ll ans = 0;

for (int i = 1; i <= n; ++i)

printf("%i64d\n",ans);

}return 0;

}

hdu 4747 Mex 線段樹區間更新

有大神部落格在。mex有兩個特徵,乙個是最小,乙個是不在集合中 首先可以看出mex是遞增的 刪掉乙個數a i 對mex l,r r對l i的影響是,a i 不在集合中了,在a i 下次出現之前,那些大於a i 的mex j 都可以被減小至a i 話說線段樹區間更新每次都寫挫 一開始pushdown ...

區間MEX 線段樹維護mex陣列

問題描述 給你乙個長度為n的數列,元素編號1到n,第i個元素值為ai。現在有m個形如 l,r 的提問,你需要回答出區間 l,r 的mex值。即求出區間 l,r 中沒有出現過的最小的非負整數。輸入格式 第一行,兩個整數n和m 第二行,n個空格間隔的整數,表示數列a 接下來m行,每行兩個整數l,r,表示...

HDU6602線段樹 思維

題意 給出乙個1e5規模數列,數字範圍也在1e5內,給出k,求最長子序列,使得序列 現的任一數字都至少出現k次。考慮列舉右端點,尺取法不好做,因為左端點沒有簡單的找法,我們這樣拆分問題 首先考慮每個數字的合法左端點的取法,易知對於數字a,若i出現不足k次,則左端點只能在最後一次a出現之後,即 最後一...