题解:直接维护最小值 然后裸线段树即可
/************************************************************** Problem: 3211 User: c20161007 Language: C++ Result: Accepted Time:1492 ms Memory:8332 kb ****************************************************************/ #include <bits/stdc++.h> #define ll long long const int MAXN=1e5+10; using namespace std; ll sum[MAXN<<2],key[MAXN],minn[MAXN<<2]; ll read(){ ll x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return f*x; } void up(int x){ sum[x]=sum[x<<1]+sum[x<<1|1]; minn[x]=max(minn[x<<1],minn[x<<1|1]); } void built(int rt,int l,int r){ if(l==r){sum[rt]=minn[rt]=key[l];return ;} int mid=(l+r)>>1; built(rt<<1,l,mid); built(rt<<1|1,mid+1,r); up(rt); } void update(int rt,int l,int r,int ql,int qr){ // cout<<minn[rt]<<endl; if(minn[rt]<=1)return ; //cout<<l<<" "<<r<<" "<<minn[rt]<<endl; if(l==r){key[l]=(ll)sqrt(key[l]);sum[rt]=minn[rt]=key[l];return ;} int mid=(l+r)>>1; if(ql<=mid)update(rt<<1,l,mid,ql,qr); if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr); up(rt); } ll ans; void querty(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ans+=sum[rt];return ;} int mid=(l+r)>>1; if(ql<=mid)querty(rt<<1,l,mid,ql,qr); if(qr>mid)querty(rt<<1|1,mid+1,r,ql,qr); } int n,q; int main(){ n=read(); for(int i=1;i<=n;i++)key[i]=read(); built(1,1,n); q=read();int op,l,r; for(int i=1;i<=q;i++){ op=read();l=read();r=read(); //cout<<l<<" "<<r<<endl; if(op==1){ans=0;querty(1,1,n,l,r);printf("%lld ",ans);} else update(1,1,n,l,r); } }
3211: 花神游历各国
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 5216 Solved: 1915
[Submit][Status][Discuss]
Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9