求助线段树 P4681
  • 板块题目总版
  • 楼主ruoo
  • 当前回复0
  • 已保存回复0
  • 发布时间2022/2/19 17:55
  • 上次更新2023/10/28 08:09:23
查看原帖
求助线段树 P4681
675921
ruoo楼主2022/2/19 17:55

为什么都RE了?

//由模数皆为小数
//且平方的性质没有更好的处理方法
//找循环节(找规律)
#include<bits/stdc++.h>
#define ll long long
#define R register int
using namespace std;
const int maxn=100010;
ll n,m,p,a,b,opt,LL,RR,ans,c[maxn]={0},vis[maxn]={0},no[maxn]={0};
struct xx
{  ll l,r,now,len,s[61],tag,lz;//对每个结点建循环节的桶 
}t[5*maxn];
queue <ll> sea;
void read(ll &x)
{  x=0;
   ll w=1;
   char ch=getchar();
   while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
   while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-48;ch=getchar();}
   x*=w;
}
void init(ll x)
{  t[x].tag=1;
   ll y=t[x].s[0];
   for(R i=1;i<=60;++i)
   {  y=y*y%p;
      if(y==t[x].s[0])
      {  t[x].len=i;
         break;
	  }
	  t[x].s[i]=y;
   }
}
void update(ll x)
{  t[x].tag=t[x<<1].tag&t[x<<1|1].tag;
   ll lw=t[x<<1].now,rw=t[x<<1|1].now;
   if(!t[x].tag)
     t[x].s[0]=t[x<<1].s[lw]+t[x<<1|1].s[rw];
   if(!t[x].tag||t[x].len)
      return;
   t[x].s[0]=(t[x<<1].s[lw]+t[x<<1|1].s[rw])%p;
   init(x);
}
void build(ll x,ll y,ll z)
{  t[z].l=x;
   t[z].r=y;
   t[z].tag=0;
   t[z].lz=0;
   t[z].now=0;
   t[z].len=0;
   if(x==y)
   {  t[z].s[0]=c[x];
      if(!no[c[x]])
        init(z);
      return;
   }
   ll mid=(x+y)>>1;
   build(x,mid,z<<1);
   build(mid+1,y,z<<1|1);
   update(z);
}
void pushdown(ll x)
{  if(!t[x].lz)
     return;
   t[x<<1].lz+=t[x].lz;
   t[x<<1|1].lz+=t[x].lz;
   t[x<<1].now=(t[x<<1].now+t[x].lz)%t[x<<1].len;
   t[x<<1|1].now=(t[x<<1|1].now+t[x].lz)%t[x<<1|1].len;
   t[x].lz=0;
}
void change(ll x,ll y,ll z)
{  if(t[z].l>=x&&t[z].r<=y)
   {  if(t[z].tag)
      {  t[z].now=(t[z].now+1)%t[z].len;
         t[z].lz++;
         return;
	  }
	  if(t[z].l==t[z].r)
	  {  t[z].s[0]=t[z].s[0]*t[z].s[0]%p;
	     if(!no[t[z].s[0]])
	       init(z);
	     return;
	  }
   }
   pushdown(z);
   //能打上lazy的点tag一定为1 
   ll mid=(t[z].l+t[z].r)>>1;
   if(mid>=x)
     change(x,y,z<<1);
   if(mid<y)
     change(x,y,z<<1|1);
   update(z);
}
ll query(ll x,ll y,ll z)
{  if(t[z].l>=x&&t[z].r<=y)
   {  ll nw=t[z].now;
      return t[z].s[nw];
   }  
   pushdown(z);
   ll mid=(t[z].l+t[z].r)>>1,ret=0;
   if(mid>=x)
     ret=query(x,y,z<<1);
   if(mid<y)
     ret+=query(x,y,z<<1|1);
   return ret; 
}
int main()
{   read(n);
    read(m);
    read(p);
    for(R i=0;i<p;++i)
      vis[i*i%p]++;//记录入度
	for(R i=0;i<p;++i)
	  if(!vis[i])
	    sea.push(i);
	while(!sea.empty())
	{  a=sea.front();
	   sea.pop();
	   no[a]=1;
	   b=a*a%p;
	   if(--vis[b]==0)
	     sea.push(b);
	}//拓扑排除不在环上的 
	for(R i=1;i<=n;++i)
	  read(c[i]);
	build(1,n,1);
	for(R i=1;i<=m;++i)
	{  read(opt);
	   read(LL);
	   read(RR);
	   if(opt==1)
	     change(LL,RR,1);
	     else
	     {  ans=query(LL,RR,1);
	        printf("%lld\n",ans);
		 }
	}
	return 0;
} 
2022/2/19 17:55
加载中...