势能分析线段树0pts求调
查看原帖
势能分析线段树0pts求调
875516
Delete_error楼主2024/11/11 19:10

在高铁手机写题,然后炸了,思路就是值为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;
}
2024/11/11 19:10
加载中...