社区讨论
次方和做法求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 条回复,欢迎继续交流。
正在加载回复...