没有看到有题解,所以在这里求助一下。
大概思路就是普通区间修改和单点查询,如果区间最小值小于等于 1 就直接 return 掉,如果区间的元素都相等就给区间打 tag。请问这个思路可不可过?如何修改?
记录(随机数据的 Subtask #4 全 WA,#5 过了#11 #13 两个点)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<ctime>
using namespace std;
const int N=1000005;
#define int long long
#define rd(n) n=read()
#define ri register int
#define lowbit(x) (x&-x)
#define INF 0x3f3f3f3f3f3f3f3f
inline int maxx(int a,int b) {return a>b?a:b;}
inline int minn(int a,int b) {return a<b?a:b;}
inline int read(){int ans=0,f=0;char ch=getchar();while(ch<'0'||ch>'9') f^=(ch=='-'),ch=getchar();while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return f?-ans:ans;}
inline void print(int n){if(n<0){putchar('-');n=-n;}if(n>9) print(n/10);putchar(n%10+'0');}
int m,n,k,tot,sum,cnt,mid,p,mod;
int u,v,w,l,r,x,y,z;
#define lson(p) p<<1
#define rson(p) p<<1|1
struct SegmentTree{
int l,r;
int dat,d;
int add,tag;
#define l(i) t[i].l
#define r(i) t[i].r
#define add(i) t[i].add
#define dat(i) t[i].dat
#define d(i) t[i].d
#define tag(i) t[i].tag
}t[N<<2];
int a[N];
inline void pushup(int p)
{
dat(p)=maxx(dat(lson(p)),dat(rson(p)));
d(p)=minn(d(lson(p)),d(rson(p)));
}
inline void build(int p,int l,int r)
{
l(p)=l; r(p)=r; tag(p)=INF;
if(l==r)
{
dat(p)=d(p)=a[l];
return;
}
int mid=(l+r)>>1;
build(lson(p),l,mid);
build(rson(p),mid+1,r);
pushup(p);
}
inline void spread(int p)
{
if(tag(p)!=INF)
{
add(lson(p))=0; tag(lson(p))=tag(p); dat(lson(p))=tag(p); d(lson(p))=tag(p);
add(rson(p))=0; tag(rson(p))=tag(p); dat(rson(p))=tag(p); d(rson(p))=tag(p);
tag(p)=INF;
}
if(add(p))
{
add(lson(p))+=add(p); add(rson(p))+=add(p);
d(lson(p))+=add(p); d(rson(p))+=add(p);
dat(lson(p))+=add(p); dat(rson(p))+=add(p);
add(p)=0;
}
}
inline void change1(int p,int l,int r,int d)
{
if(l<=l(p)&&r>=r(p))
{
add(p)+=d;
dat(p)+=d;
d(p)+=d;
return;
}
spread(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid) change1(lson(p),l,r,d);
if(r>mid) change1(rson(p),l,r,d);
pushup(p);
}
inline void change2(int p,int l,int r)
{
if(dat(p)<=1) return;
if(d(p)==dat(p))
{
int d=__builtin_popcountll(dat(p));
add(p)=0; tag(p)=d;
dat(p)=d; d(p)=d;
return;
}
spread(p);
int mid=(l(p)+r(p))>>1;
if(l<=mid) change2(lson(p),l,r);
if(r>mid) change2(rson(p),l,r);
pushup(p);
}
inline int query(int p,int x)
{
if(l(p)==r(p)) return dat(p);
spread(p);
int mid=(l(p)+r(p))>>1;
if(x<=mid) return query(lson(p),x);
else return query(rson(p),x);
}
signed main(void)
{
// freopen("seg.txt","r",stdin);
// freopen("segout.txt","w",stdout);
// clock_t start,end;
// start=clock();
rd(n); rd(m);
for(ri i=1;i<=n;++i) rd(a[i]);
build(1,1,n);
char op[2];
for(ri i=1;i<=m;++i)
{
scanf("%s",op);
if(op[0]=='A')
{
rd(l); rd(r); rd(x);
if(l>r) swap(l,r);
change1(1,l,r,x);
}
else if(op[0]=='P')
{
rd(l); rd(r);
if(l>r) swap(l,r);
change2(1,l,r);
}
else
{
rd(x);
print(query(1,x));
putchar('\n');
}
}
// end=clock();
// puts("");
// cout<<(double)(end-start);
return 0;
}
/*
5 5
1 2 3 4 5
J 2
A 2 4 3
J 4
P 1 4
J 3
----------------
2 7 2
4 8
1 2 1 2
A 1 4 2
P 1 4
A 1 4 2
P 1 4
J 1
J 2
J 3
J 4
----------------
1 2 1 2
*/