【bzoj3211】花神游历各国

来源:互联网 发布:mysql排序语句 编辑:程序博客网 时间:2024/06/10 03:56

其实这是一道sb题……
哦不其实是两道2333333(还有3038也是同一题)
然而在写3038的时候由于数据太水直接就A掉了。。。
刚刚拿之前的code交上去就WA啦。。。
不能判断区间和是否==r-l+1因为会出现0……所以要开多一个东西表示这个区间还有多少个数不会再改变了
每个数可以开方的次数是很小的,就当做是常数非常小的O(logn)
这样复杂度就是O(nlog2n)

#include <bits/stdc++.h>#define lc (u << 1)#define rc (u << 1 | 1)#define T int u = 1 , int l = 1 , int r = n#define L lc , l , m#define R rc , m + 1 , r#define rep(i,a,b) for(int i = a;i <= b;i ++)#define maxn 100007typedef long long ll;ll rd() {    char c = getchar();    while (!isdigit(c)) c = getchar( ) ; ll x = c - '0';    while (isdigit(c = getchar())) x = x * 10 + c - '0';    return x;}ll sum[maxn * 4 + 1] , cnt[maxn * 4 + 1] , a[maxn];ll n , m , ql , qr;void build(T) {    if (l == r)         { sum[u] = a[l] , cnt[u] = (a[l] <= 1) ; return ; }    int m = (l + r) >> 1;    build(L) , build(R);    sum[u] = sum[lc] + sum[rc];    cnt[u] = cnt[lc] + cnt[rc];}void modi(T) {    if (cnt[u] == r - l + 1)        return ;    if (l == r)        { sum[u] = (ll)sqrt(sum[u]) , cnt[u] = (sum[u] <= 1) ; return ; }    int m = (l + r) >> 1;    if (ql <= m) modi(L);    if (qr >  m) modi(R);    sum[u] = sum[lc] + sum[rc];    cnt[u] = cnt[lc] + cnt[rc];}ll que(T) {    if (ql <= l && r <= qr)        return sum[u];    int m = (l + r) >> 1;    ll ret = 0;    if (ql <= m) ret += que(L);    if (qr >  m) ret += que(R);    return ret;}void input() {    n = rd();    rep(i , 1 , n) a[i] = rd();    build();}void solve() {    m = rd();    rep(i , 1 , m) {        int k = rd();        ql = rd() , qr = rd();        if (ql > qr) std::swap(ql , qr);        if (k == 1) printf("%lld\n" , que());        else modi();    }}int main() {    input();    solve();    return 0;}
0 0
原创粉丝点击