清華集訓 序列操作

2022-05-16 10:20:47 字數 1814 閱讀 1427

寫了這麼多資料結構題,一半左右是線段樹

線段樹真是優秀啊

有乙個長度為n的序列,有三個操作:

1.i a b c表示將\([a,b]\)這一段區間的元素集體增加\(c\)

2.r a b表示將\([a,b]\)區間內所有元素變成相反數

3.q a b c表示詢問\([a,b]\)這一段區間中選擇\(c\)個數相乘的所有方案的和\(\mod 19940417\)的值(\(1 \leq c \leq 20\))

首先考慮維護哪些資訊

顯然需要維護乙個陣列表示答案

然後考慮合併

顯然\(f[rt][n]=f[ls][n]+f[rs][n]+\sum_^\)

再考慮維護哪些標記

區間加法,區間反轉

考慮標記的維護

顯然先維護反轉標記後維護加法標記

最後考慮修改答案

區間反轉只需把乘奇數個數的答案反轉

區間加法類似二項式定理可以推出(好吧其實和二項式定理沒有什麼關係)

\(f[rt][n]=f[rt][n]+ \sum_^^* k^i } + c_^i * k^n\)

因為前面的值會影響後面的,所以從後往前更新

#includeusing namespace std;

#define gc c=getchar()

#define r(x) read(x)

#define ll long long

#define ls (rt<<1)

#define rs (rt<<1|1)

templateinline void read(t&x)

while(isdigit(c))x*=k;

}const int n=1e5+7;

const int p=19940417;

ll c[n][21];

struct seg

inline const ll& operator (const int &x)const

inline ll& operator (const int &x)

inline void reverse()

inline void increase(int x)

(a[i]+=c[siz][i]*tmp)%=p;}}

}tr[n<<2];

inline seg operator + (const seg &a,const seg &b)

void reverse(int rt,int l,int r,int x,int y)

pushdown(rt);

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

if(x<=mid)reverse(ls,l,mid,x,y);

if(y>mid)reverse(rs,mid+1,r,x,y);

update(rt);

}void increase(int rt,int l,int r,int x,int y,int v)

pushdown(rt);

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

if(x<=mid)increase(ls,l,mid,x,y,v);

if(y>mid)increase(rs,mid+1,r,x,y,v);

update(rt);

}seg query(int rt,int l,int r,int x,int y)

inline void pre(int n)

}}int main()

case 'r':

case 'q':}}

}

BZOJ2962 清華集訓 序列操作

bzoj luogu 有乙個長度為 n 的序列,有三個操作 i a b c 表示將 a,b 這一段區間的元素集體增加 c r a b 表示將 a,b 區間內所有元素變成相反數 q a b c 表示詢問 a,b 這一段區間中選擇 c 個數相乘的所有方案的和 mod19940417 的值。對於100 的...

清華集訓 2014 玄學

update text update 我之前講的是個什麼鬼 如果想看看人話版本 戳這。感覺自己被坑騙了。題目明明寫了所有資料不超過int,敢情是輸入資料不超int?迷惑行為 題目感覺有點繞,我盡量 不口胡。首先我們搞一顆線段樹1,樹表示插入序列的編號。如,在q行中第i個出現插入操作 其實拿到這道題我...

清華集訓2016 汽水

試題描述 牛牛來到了乙個盛產汽水的國度旅行。這個國度的地圖上有n個城市,這些城市之間用 n 1 條道路連線,任意兩個城市之間,都存在一條路徑連線。這些城市生產的汽水有許多不同的風味,在經過道路 i 時,牛牛會喝掉 wi 的汽水。牛牛非常喜歡喝汽水,但過量地用汽水是有害健康的,因此,他希望在他旅行的這...