CodeForces 438D (线段树)

匿名 (未验证) 提交于 2019-12-03 00:36:02

题意:
三种操作:
1lr:i=lrai
2lrx: 对所有i[l,r], ai=aimodx
3kx:ak=x
思路:
神一般的复杂度分析。。。。记录区间最大值,如果x比区间最大值还大,显然不更新,否则暴力更新。因为如果是ymodx的话,如果x>y2,那么y取模之后小于y2,如果x<y2,取模之后也y2,故每个数取模不会超过logn次。。。

#include<bits/stdc++.h> typedef long long ll; const int maxn = 1e5 + 10; using namespace std;  ll sum[maxn * 4], val[maxn * 4];  void build(int o, int l, int r) {     if(l == r) { cin >> sum[o]; val[o] = sum[o]; return ; }     int mid = (l + r) >> 1;     build(o << 1, l, mid);     build(o << 1 | 1, mid + 1, r);     val[o] = max(val[o << 1], val[o << 1 | 1]);     sum[o] = sum[o << 1] + sum[o << 1 | 1]; }  void update_set(int o, int l, int r, int ind, int x) {     if(l == r) { val[o] = sum[o] = x; return ; }     int mid = (l + r) >> 1;     if(ind <= mid) update_set(o << 1, l, mid, ind, x);     else update_set(o << 1 | 1, mid + 1, r, ind, x);     sum[o] = sum[o << 1] + sum[o << 1 | 1];     val[o] = max(val[o << 1], val[o << 1 | 1]); }  void update_mod(int o, int l, int r, int ql, int qr, int mod) {     if(l > qr || r < ql) return ;     if(l >= ql && r <= qr && val[o] < mod) return ;      if(l == r) { sum[o] %= mod; val[o] = sum[o]; return ; }     int mid = (l + r) >> 1;     int o1 = o << 1, o2 = o1 | 1;     update_mod(o1, l, mid, ql, qr, mod);     update_mod(o2, mid + 1, r, ql, qr, mod);     sum[o] = sum[o1] + sum[o2];     val[o] = max(val[o1], val[o2]); }  ll query(int o, int l, int r, int ql, int qr) {     if(l > qr || r < ql) return 0;     if(l >= ql && r <= qr) return sum[o];     int mid = (l + r) >> 1, o1 = o << 1, o2 = o1 | 1;     ll p1 = query(o1, l, mid, ql, qr);     ll p2 = query(o2, mid + 1, r, ql, qr);     return p1 + p2; }  int main() {     ios::sync_with_stdio(0);     int n, m, T, kase = 1;     cin >> n >> m;     build(1, 1, n);     while(m--) {         int op, l, r, x;         cin >> op;         if(op == 1) {             cin >> l >> r;             cout << query(1, 1, n, l, r) << endl;         } else if(op == 2) {             cin >> l >> r >> x;             update_mod(1, 1, n, l, r, x);         } else {             cin >> l >> x;             update_set(1, 1, n, l, x);         }     }     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!