社区讨论

次方和做法求hack

P6688可重集参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@misbjhd1
此快照首次捕获于
2025/12/05 11:42
3 个月前
此快照最后确认于
2025/12/06 23:28
2 个月前
查看原帖
思路:维护区间最值和 1/2/3/4 次方和,通过区间最值计算 k 然后用次方和验证是否合规。
但是被每个 subtask 的第一个点卡掉了。
求本质不同但区间最值和 1/2/3/4 次方和都符合公式的两段区间。
代码:
CPP
#include<iostream>
#include<set>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
namespace KitoTaisu{
	char *p1,*p2,buf[32769];
	#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,32767,stdin),p1==p2)?EOF:*p1++)
	int read(){
		int x=0,f=1;
		char ch=nc();
		while(ch<48||ch>57){
			if(ch=='-')f=-1;
			ch=nc();
		}
		while(47<ch&&ch<58){
			x=(x<<1)+(x<<3)+(ch^48);
			ch=nc();
		}
		return x*f;
	}
	unsigned int readu(){
		unsigned int x=0;
		char ch=nc();
		while(ch<48||ch>57){
			ch=nc();
		}
		while(47<ch&&ch<58){
			x=(x<<1)+(x<<3)+(ch^48);
			ch=nc();
		}
		return x;
	}
	long long readll(){
		long long x=0,f=1;
		char ch=nc();
		while(ch<48||ch>57){
			if(ch=='-')f=-1;
			ch=nc();
		}
		while(47<ch&&ch<58){
			x=(x<<1)+(x<<3)+(ch^48);
			ch=nc();
		}
		return x*f;
	}
	unsigned long long readull(){
		unsigned long long x=0;
		char ch=nc();
		while(ch<48||ch>57){
			ch=nc();
		}
		while(47<ch&&ch<58){
			x=(x<<1)+(x<<3)+(ch^48);
			ch=nc();
		}
		return x;
	}
	int readstr(char* str,char vl='a',char vr='z'){
		int len=0;
		char ch=nc();
		while(ch<vl||ch>vr){
			ch=nc();
		}
		while(vl<=ch&&ch<=vr){
			str[len++]=ch;
			ch=nc();
		}
		str[len]=0;
		return len;
	}
}
namespace Chtholly{
	struct Chtholly{
		int l,r;
		mutable int val;
		bool operator <(const Chtholly a)const{
			return l<a.l;
		}
	};
	#define si set<Chtholly>::iterator
	class ChthollyTree{
		private:
			set<Chtholly> tree;
			si split(int x){
				si it=tree.lower_bound({x,0,0});
				if(it!=tree.end()&&it->l==x)return it;
				--it;
				int l=it->l,r=it->r,val=it->val;
				tree.erase(it);
				tree.insert({l,x-1,val});
				return tree.insert({x,r,val}).first;
			}
			si get(int x){
				si it=tree.lower_bound({x,0,0});
				if(it!=tree.end()&&it->l==x)return it;
				--it;
				return it;
			}
		public:
			inline void build(int l,int r,int val,bool pr=1){
				tree.insert({l,r,val});
				if(pr)tree.insert({r+1,r+1,val});
			}
			void assign(int l,int r,int val){
				si itr=split(r+1),itl=split(l);
				tree.erase(itl,itr);
				tree.insert({l,r,val});
			}
			void change(int l,int r,int x){
				si itr=split(r+1),itl=split(l);
				for(si it=itl;it!=itr;++it){
					it->val+=x;
				}
			}
			void print(){
				si itr=tree.end(),itl=tree.begin();
				for(si it=itl;it!=itr;++it){
					printf("Chtholly %d %d %d\n",it->l,it->r,it->val);
				}
			}
	};
	#undef si
	#define ls (id<<1)
	#define rs ((id<<1)|1)
	class SegmentTree{
		private:
			long long val[4000002],lazy[400002];
			inline void push_up(int id){
				val[id]=val[ls]+val[rs];
			}
			inline void push_down(int id){
				val[ls]+=lazy[id];
				lazy[ls]+=lazy[id];
				val[rs]+=lazy[id];
				lazy[rs]+=lazy[id];
				lazy[id]=0;
			}
		public:
			void build(int id,int l,int r,int* a){
				if(l==r){
					val[id]=a[l];
					return;
				}
				int mid=(l+r)>>1;
				build(ls,l,mid,a);
				build(rs,mid+1,r,a);
				push_up(id);
			}
			void add(int id,int l,int r,int L,int R,int x){
				if(l>R||L>r)return;
				if(L<=l&&r<=R){
					val[id]+=x;
					lazy[id]+=x;
					return;
				}
				push_down(id);
				int mid=(l+r)>>1;
				add(ls,l,mid,L,R,x);
				add(rs,mid+1,r,L,R,x);
				push_up(id);
			}
			long long query(int id,int l,int r,int L,int R){
				if(l>R&&L>r)return 0;
				if(L<=l&&r<=R){
					return val[id];
				}
				long long ret=0;
				push_down(id);
				int mid=(l+r)>>1;
				ret=query(ls,l,mid,L,R)+query(rs,mid+1,r,L,R);
				push_up(id);
				return ret;
			}
	};
	struct H_infrm_type{
		long long sum,sqs;
		int xrs,Max,Min,len;
		__int128 trs,sps;
		H_infrm_type operator +(H_infrm_type a){
			return {sum+a.sum,sqs+a.sqs,xrs^a.xrs,max(Max,a.Max),min(Min,a.Min),len+a.len,trs+a.trs,sps+a.sps};
		}
	};
	class HashTree{
		private:
			H_infrm_type val[4000002];
			inline void push_up(int id){
				val[id]=val[ls]+val[rs];
			}
		public:
			void build(int id,int l,int r,int* a){
				if(l==r){
					val[id].sum=val[id].Max=val[id].Min=val[id].xrs=a[l];
					val[id].sqs=1ll*a[l]*a[l];
					val[id].trs=(val[id].trs=1)*a[l]*a[l]*a[l];
					val[id].sps=(val[id].sps=1)*a[l]*a[l]*a[l]*a[l];
					val[id].len=1;
					return;
				}
				int mid=(l+r)>>1;
				build(ls,l,mid,a);
				build(rs,mid+1,r,a);
				push_up(id);
			}
			void change(int id,int l,int r,int x,int v){
				if(x<l||r<x)return;
				if(l==r){
					val[id].sum=val[id].Max=val[id].Min=val[id].xrs=v;
					val[id].sqs=1ll*v*v;
					val[id].trs=(val[id].trs=1)*v*v*v;
					val[id].sps=(val[id].sps=1)*v*v*v*v;
					return;
				}
				int mid=(l+r)>>1;
				change(ls,l,mid,x,v);
				change(rs,mid+1,r,x,v);
				push_up(id);
			}
			H_infrm_type query(int id,int l,int r,int L,int R){
				if(r<L||R<l)return {0,0,0,0,1000000,0,0,0};
				if(L<=l&&r<=R)return val[id];
				int mid=(l+r)>>1;
				return query(ls,l,mid,L,R)+query(rs,mid+1,r,L,R);
			}
	};
	#undef ls
	#undef rs
	class VST{
		private:
			int tot,ls[4000002],rs[4000002],Max[4000002];
			long long sum[4000002];
			inline void push_up(int id){
				Max[id]=sum[id]=0;
				if(ls[id]){
					Max[id]=max(Max[ls[id]],Max[id]);
					sum[id]+=sum[ls[id]];
				}
				if(rs[id]){
					Max[id]=max(Max[rs[id]],Max[id]);
					sum[id]+=sum[rs[id]];
				}
			}
		public:
			void insert(int id,int l,int r,int x){
				if(l==r){
					sum[id]+=x;
					Max[id]=x;
					return;
				}
				int mid=(l+r)>>1;
				if(x<=mid)insert(ls[id]?ls[id]:(ls[id]=++tot),l,mid,x);
				else insert(rs[id]?rs[id]:(rs[id]=++tot),mid+1,r,x);
				push_up(id);
			}
			int get_Max(){
				return Max[1];
			}
	};
	class ts{
		private:
			int c[1000002];
		public:
			inline int lowbit(int x){
				return x&(-x);
			}
			inline void add(int x){
				for(int i=x;i<1000001;i+=lowbit(i))c[i]++;
			}
			inline int query(int x){
				int ret=0;
				for(int i=x;i;i-=lowbit(i))ret+=c[i];
				return ret;
			}
	};
}
using KitoTaisu::read;
using KitoTaisu::readu;
using KitoTaisu::readll;
using KitoTaisu::readull;
using KitoTaisu::readstr;
using Chtholly::ChthollyTree;
using Chtholly::SegmentTree;
using Chtholly::VST;
using Chtholly::ts;
using Chtholly::H_infrm_type;
using Chtholly::HashTree;
int n,q,rd[1000002];
bool check(H_infrm_type a,H_infrm_type b){
	//printf("Algebra %lld %lld %d %d %d %d  %lld %lld %d %d %d %d\n",a.sum,a.sqs,a.xrs,a.Max,a.Min,a.len,b.sum,b.sqs,b.xrs,b.Max,b.Min,b.len);
	if(a.len!=b.len)return false;
	int k=a.Max-b.Max;
	if(k!=a.Min-b.Min)return false;
	if(1ll*k*a.len!=a.sum-b.sum)return false;
	if(1ll*k*k*a.len+2ll*k*b.sum!=a.sqs-b.sqs)return false;
	if((__int128)(1)*k*k*k*a.len+(__int128)(3)*k*k*b.sum+(__int128)(3)*k*b.sqs!=a.trs-b.trs)return false;
	if((__int128)(1)*k*k*k*k*a.len+(__int128)(4)*k*k*k*b.sum+(__int128)(6)*k*k*b.sqs+(__int128)(4)*k*b.trs!=a.sps-b.sps)return false;
	//if(k*(a.len&1)!=a.xrs^b.xrs)return false;
	return true;
}
HashTree tr;
int main(){
	n=read(),q=read();
	for(int i=1;i<=n;++i)rd[i]=read();
	tr.build(1,1,n,rd);
	while(q--){
		rd[0]=read();
		if(rd[0]){
			rd[1]=read(),rd[2]=read(),rd[3]=read(),rd[4]=read();
			if(check(tr.query(1,1,n,rd[1],rd[2]),tr.query(1,1,n,rd[3],rd[4])))printf("YES\n");
			else printf("NO\n");
		}
		else{
			rd[1]=read(),rd[2]=read();
			tr.change(1,1,n,rd[1],rd[2]);
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...