社区讨论
求助,注释齐全
CF213E Two Permutations参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lwvxgtzi
- 此快照首次捕获于
- 2024/06/01 17:45 2 年前
- 此快照最后确认于
- 2024/06/01 19:48 2 年前
问题可能出在关于base上,当base为10时,可以通过#14,当base为13331时,不能通过#14
CPP#include<iostream>
#include<map>
#define int long long
using namespace std;
const int N=200010;
const int base=13331;
const int P=1000000007;
map<int,int> mp;
int QWQ=0;
struct info
{
int sum,cnt;//和 和 数的个数
};
struct node
{
int tag;
info v;
}tr[N*4];
int n,m,a[N],b[N],in,h[N],pos[N],tmp;
int powq(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a%P;
a=a*a%P;
b=b>>1;
}
return ans;
}
info merge(info a,info b)
{
info c;
c.sum=(a.sum+b.sum)%P;
c.cnt=a.cnt+b.cnt;
return c;
}
void update(int x)
{
tr[x].v=merge(tr[x*2].v,tr[x*2+1].v);
}
void maketag(int x,int k,int L,int r)
{
tr[x].v.sum=tr[x].v.sum*k%P;
tr[x].tag=tr[x].tag*k%P;
}
void pushdown(int x,int L,int R)
{
if(L==R)
return;
int mid=(L+R)/2;
maketag(x*2,tr[x].tag,L,mid);
maketag(x*2+1,tr[x].tag,mid+1,R);
tr[x].tag=1;
}
void modify(int x,int l,int r,int k,int L,int R)//区间乘线段树
{
pushdown(x,L,R);
if(l==L&&R==r)
{
maketag(x,k,L,R);
return;
}
int mid=(L+R)/2;
if(r<=mid)
modify(x*2,l,r,k,L,mid);
else if(l>=mid+1)
modify(x*2+1,l,r,k,mid+1,R);
else
{
modify(x*2,l,mid,k,L,mid);
modify(x*2+1,mid+1,r,k,mid+1,R);
}
update(x);
}
void modify(int x,int pos,int k,int L,int R)//单点赋值线段树
{
pushdown(x,L,R);
if(L==R)
{
tr[x].v.sum=k;
tr[x].v.cnt=(k!=0);
return;
}
int mid=(L+R)/2;
if(pos<=mid)
modify(x*2,pos,k,L,mid);
else
modify(x*2+1,pos,k,mid+1,R);
update(x);
}
info find(int x,int l,int r,int L,int R)
{
pushdown(x,L,R);
if(l==L&&r==R)
return tr[x].v;
int mid=(L+R)/2;
if(r<=mid)
return find(x*2,l,r,L,mid);
if(l>=mid+1)
return find(x*2+1,l,r,mid+1,R);
return merge(find(x*2,l,mid,L,mid),find(x*2+1,mid+1,r,mid+1,R));
}
void built(int x,int l,int r)
{
tr[x].tag=1;
if(l==r)
return;
int mid=(l+r)/2;
built(x*2,l,mid);
built(x*2+1,mid+1,r);
update(x);
}
signed main()
{
cin>>n>>m;
h[0]=1;
int now=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
now=(now*base+a[i])%P;
h[i]=h[i-1]*base%P;
tmp=(tmp+h[i-1])%P;
}//哈希
built(1,0,m+1);//建树,将所有标记设为1
for(int i=0;i<=m-n;i++)
mp[(now+i*tmp%P)%P]=1;//记录a数组所有可能值
in=powq(base,P-2);//除数
for(int i=1;i<=m;i++)
{
cin>>b[i];
pos[b[i]]=i;
}
int ans=0;
for(int i=1;i<=n;i++)
{
int x=pos[i];
modify(1,0,x-1,base,0,m+1);
int cnt=find(1,x+1,m+1,0,m+1).cnt;
modify(1,x,h[cnt]*i%P,0,m+1);
}
if(mp[find(1,0,m+1,0,m+1).sum%P])
ans++;
for(int i=n+1;i<=m;i++)
{
int x=pos[i-n];
modify(1,0,x-1,in,0,m+1);//除以前面的数
modify(1,x,0,0,m+1);//去掉此数
x=pos[i];
modify(1,0,x-1,base,0,m+1);//前面统一乘
int cnt=find(1,x+1,m+1,0,m+1).cnt;//后面的个数
modify(1,x,h[cnt]*i%P,0,m+1);//加上这一位
if(mp[find(1,0,m+1,0,m+1).sum%P])
ans++;
}
cout<<ans;
}
/*
4 8
2 4 1 3
3 6 8 5 4 2 7 1
*/
回复
共 0 条回复,欢迎继续交流。
正在加载回复...