[BZOJ 2054]疯狂的馒头
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ 2054]疯狂的馒头
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?
這題一看是區(qū)間染色,直接上線段樹。數(shù)據(jù)范圍N<= 106,M <= 107,如果跑線段樹復(fù)雜度為O(MlogN),但是時間限制10s,所以復(fù)雜度能過。
具體操作就是倒著算區(qū)間,因為每個饅頭最后的顏色是最后一次染上的顏色,如果我們倒著染色,那么被染色過的點就是最后的顏色,之后再染這個點就沒用了。所以直接上代碼:
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define N 1000100 #define ls (x << 1) #define rs (x << 1 | 1) #define mid ((l + r) >> 1) using namespace std; int tree[4 * N]; void push_up(int x) {tree[x] = tree[ls] && tree[rs];//除了葉子節(jié)點之外的點只需要保存是否染過色就行return; } void modify(int x,int nl,int nr,int l,int r,int k) {if(tree[x]) return;if(l == r) {tree[x] = k;//葉子節(jié)點直接保存顏色return;}if(nl <= mid) modify(ls,nl,nr,l,mid,k);if(nr > mid) modify(rs,nl,nr,mid + 1,r,k);push_up(x);return; } void print(int x,int l,int r) {if(l == r) {printf("%d\n",tree[x]);//輸出葉子節(jié)點return;}print(ls,l,mid);print(rs,mid + 1,r); } int p,q,n,m; int main() {scanf("%d %d %d %d",&n,&m,&p,&q);for(int i = m;i >= 1;i--){int l = (int)((long long)(i * p + q) % n + 1ll);//這里強制類型轉(zhuǎn)換防止在做乘法的時候爆intint r = (int)((long long)(i * q + p) % n + 1ll);if(l > r) swap(l,r);modify(1,l,r,1,n,i);}print(1,1,n); }?
轉(zhuǎn)載于:https://www.cnblogs.com/lijilai-oi/p/10945070.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ 2054]疯狂的馒头的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集合已修改,可能无法执行枚举操作
- 下一篇: JQuery多个异步操作后执行(reso