div.1 D线段树求调
查看原帖
div.1 D线段树求调
749325
Sincerin楼主2023/1/24 20:56

没有看到有题解,所以在这里求助一下。

大概思路就是普通区间修改和单点查询,如果区间最小值小于等于 11 就直接 return 掉,如果区间的元素都相等就给区间打 tag\operatorname{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
*/
2023/1/24 20:56
加载中...