寫了這麼多資料結構題,一半左右是線段樹
線段樹真是優秀啊
有乙個長度為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 的汽水。牛牛非常喜歡喝汽水,但過量地用汽水是有害健康的,因此,他希望在他旅行的這...