在高铁手机写题,然后炸了,思路就是值为1打标记,然后线段树,思路应该是对的(?,有tle有wa。
#include<bits/stdc++.h>
using namespace std;
#define inll long long
//#define inll __int128
#define lp p<<1
#define rp p<<1|1
#define mid ((l+r)>>1)
const int MAXN=1e5+5;
inll n,m,op;
inll a[MAXN],l,r;
struct Node{
inll tag,sum;
}tree[MAXN<<2];
inll sol(inll x,inll y){
return x&y;
}
void push_up(inll p){
tree[p].tag=sol(tree[lp].tag,tree[rp].tag);
tree[p].sum=tree[lp].sum+tree[rp].sum;
}
void build(inll l,inll r,inll p){
if(l==r){
tree[p].sum=a[l];
if(tree[p].sum==1) tree[p].tag=1;
return;
}
build(l,mid,lp);
build(mid+1,r,rp);
push_up(p);
}
void update(inll l,inll r,inll ql,inll qr,inll p){
if(tree[p].tag) return;
if(l==r){
tree[p].sum=sqrt(tree[p].sum);
if(tree[p].sum==1) tree[p].tag=1;
return;
}
if(ql<=mid) update(l,mid,ql,qr,lp);
if(qr>mid) update(mid+1,r,ql,qr,rp);
push_up(p);
}
inll query(inll l,inll r,inll ql,inll qr,inll p){
inll ans=0;
if(ql<=l&&r<=qr){
return tree[p].sum;
}
if(ql<=mid) ans=(ans+query(l,mid,ql,qr,lp));
if(qr>mid) ans=(ans+query(mid+1,r,ql,qr,rp));
return ans;
}
inll read(){
inll x=0,sgn=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') sgn=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*sgn;
}
void write(inll x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int main(){
//ios::sync_with_stdio(0);
//cin.tie(0),cout.tie(0);
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,n,1);
while(m--){
op=read();
l=read(),r=read();
if(l>r) swap(l,r);
if(op==0){
update(1,n,l,r,1);
}
else write(query(1,n,l,r,1)),cout<<"\n";
}
return 0;
}