# 洛谷3月月赛II T2-4简要题解

## T2 无论怎样神树大人都会删库跑路

#include<bits/stdc++.h>
#define pii pair<int,int>
#define mkp make_pair
#define fi first
#define sc second
#define gc getchar
#define pb push_back
using namespace std;
const int N=1e5+10,p1=1e9+7,p2=1e9+9,bs=1e5+7;
typedef long long ll;
typedef double db;

int n,T,q,m,R[N],sz[N],a[N];
int r[N],gx[N],rnd,L,t[N];
pii pw[N],ori,v,nw;ll ans,whl;
vector<pii>hz[N];

char cp;
inline int rd()
{
cp=gc();int x=0,f=1;
for(;!isdigit(cp);cp=gc()) if(cp=='-') f=-1;
for(;isdigit(cp);cp=gc()) x=x*10+(cp^48);
return f*x;
}

inline int ad(int x,int y,int p){x+=y;return x>=p?x-p:x;}
inline int dc(int x,int y,int p){x-=y;return x<0?x+p:x;}
inline pii operator *(pii a,int b){return mkp((ll)a.fi*b%p1,(ll)a.sc*b%p2);}
inline pii operator -(pii a,pii b){return mkp(dc(a.fi,b.fi,p1),dc(a.sc,b.sc,p2));}
inline pii operator *(pii a,pii b){return mkp((ll)a.fi*b.fi%p1,(ll)a.sc*b.sc%p2);}

struct P{int id,len;}tp;
deque<P>que;

inline void upd(int x)
{
nw=nw+hz[x][sz[x]];L+=sz[x];
que.push_back((P){x,sz[x]});
for(;L>T;){
tp=que.front();que.pop_front();nw=nw-hz[tp.id][tp.len];
if(L-tp.len>=T) L-=tp.len;else{
nw=nw+hz[tp.id][T-L+tp.len];
que.push_front((P){tp.id,T-L+tp.len});L=T;
}
}
}

int main(){
int i,j,x,y,mx=0;pw[0]=mkp(1,1);
for(i=1;i<N;++i) pw[i]=pw[i-1]*bs;
n=rd();T=rd();q=rd();
for(i=1;i<=T;++i) ori=ori+pw[rd()+1];
for(i=1;i<=n;++i){
sz[i]=x=rd();hz[i].resize(x+1);v.fi=v.sc=0;
for(j=1;j<=x;++j) {a[j]=rd()+1;v=v+pw[a[j]];}
for(j=x;j>0;--j) {hz[i][j]=v;v=v-pw[a[x-j+1]];}
}
for(m=rd(),i=1;i<=m;++i) whl+=sz[(r[i]=rd())];
rnd=((T-1)/whl+1)*m;
for(i=1;i<=q && i<=rnd;++i){upd(r[(i-1)%m+1]);ans+=(L==T && ori==nw);}
for(i=1;i<=m && rnd+i<=q;++i){upd(r[(i-1)%m+1]);gx[i]=gx[i-1]+(ori==nw);}
if(q>rnd) ans+=(ll)gx[m]*((q-rnd)/m)+gx[q%m];
printf("%lld",ans);
return 0;
}



## T3 OwenOwl 不学车也不删库

std

#include<bits/stdc++.h>
#define pb push_back
#define gc getchar
using namespace std;
const int N=2010;
typedef long long ll;
typedef double db;

int n=1,p,k,dlt,q[N];
bool g[N][N];

inline int cal(int x,int y)
{
int re=0,i,j,pw=1;
for(i=0;i<k;++i,pw*=p,x/=p,y/=p)
re+=(p+x%p+y%p)%p*pw;
return re;
}

int main(){
int i,j,x,y;
scanf("%d%d",&p,&k);puts("YES");
for(i=1;i<=k;++i) n*=p;
for(i=0;i<n;++i)
for(j=i+1;j<n;++j) if(!g[i][j]){
dlt=cal(j,-i);q[0]=i;
for(x=1;x<p;++x) q[x]=cal(q[x-1],dlt);
for(x=0;x<p;++x){
printf("%d ",q[x]);
for(y=0;y<p;++y)
g[q[x]][q[y]]=true;
}
putchar('\n');
}
return 0;
}


## T4 总而言之神J要去练习篮球

int cal(int r1,int r2,int x){
int R=r1^r2;
int ans=0;
for(int i=30;i>=0;--i){
if(((r1>>i&1)||(r2>>i&1))){
int a=r1>>i&1,b=r2>>i&1,c=x>>i&1;
int d=(1<<i);
if(a&&(b==c))ans+=r2%d+1;
if(b&&(a==c))ans+=r1%d+1;
if(a&&b&&0==c)ans+=d;
}
if((x>>i&1)!=(R>>i&1))break;
}
return ans+(x==R);
}


• $x_1 \ xor \ (x_1+1),...,(x_1+w-2)\ xor \ (x_1+w-1) \ = \ x_2 \ xor \ (x_2+1),...,(x_2+w-2)\ xor \ (x_2+w-1)$$y_1,y_2$同理
• $a[x_1][y_1]=a[x_2][y_2]$

$x_1,x_2$序列相等，则必须满足后$k$位相同，相当于是一个$2^k$的循环节。
$y_1,y_2$同理。

#include<bits/stdc++.h>
typedef long long ll;
#define pii pair<ll,ll>
#define mkp make_pair
#define fi first
#define sc second
#define gc getchar
#define pb push_back
using namespace std;
const int mod=1e9+7;
typedef double db;

int tk,W,H,K,ans;
vector<pii>a;

inline void ad(int &x,int y){x+=y;if(x>=mod) x-=mod;}
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}

/*single point*/
inline void mk(vector<pii>&v,int l,int r,ll vl)
{if(vl){v.pb(mkp(l,vl));v.pb(mkp(r,-vl));}}

//模拟数位DP 枚举所有数
void mat(int x,int y,vector<pii>&v,int pr)
{
if(x<0 || y<0) return;
int a,b,c,d,i,R=(x^y),res=0;
for(i=30;i>=0;--i){

//枚举第一次分离的位

res|=(R&d);
if(a&&(b==c)) ss+=(y%d)+1;
if(b&&(a==c)) ss+=(x%d)+1;
if(a&&b&&(c==0)) ss+=d;
}
mk(v,res,res+1,pr*(ss+1));
}

void Single_sol(int lx,int rx,int ly,int ry,ll cnt)
{
if(lx>rx || ly>ry) return;
vector<pii>re;int i,sz;ll ss=0;
mat(rx,ry,re,1);mat(lx-1,ry,re,-1);mat(rx,ly-1,re,-1);mat(lx-1,ly-1,re,1);
sort(re.begin(),re.end());sz=re.size();
for(i=0;i<sz;++i){
ss+=re[i].sc;
if(ss && i+1<sz && re[i+1].fi>re[i].fi) a.pb(mkp(ss,cnt*(re[i+1].fi-re[i].fi)%mod));
}
}

/* step by step (2^k)*/
struct P{ll d;int l,r;};

inline void ins(int l,int r,int ql,int qr,vector<P>&v)
{if(l<=r && ql<=qr) v.pb((P){r-l+1,ql,qr});}

inline void nd(int lx,int rx,int liml,int limr,int stp,vector<P>&v)
{
int L=max(lx%stp,liml),R=min(rx%stp,limr),l=lx/stp,r=rx/stp;
if(L<=R){
ins(liml,L-1,l+1,r,v);
ins(L,R,l,r,v);
ins(R+1,limr,l,r-1,v);
}else{
ins(liml,R,l+1,r,v);
ins(max(liml,R+1),min(limr,L-1),l+1,r-1,v);
ins(L,limr,l,r-1,v);
}
}

//x*2^k xor y*2^k = X
inline void Step_sol(int lx,int rx,int ly,int ry,int llx,int lrx,int lly,int lry,int k)
{
if(llx>lrx || lly>lry) return;
vector<P>ra,rb;
nd(lx,rx,llx,lrx,1<<k,ra);nd(ly,ry,lly,lry,1<<k,rb);
for(P a:ra)
for(P b:rb)
Single_sol(a.l,a.r,b.l,b.r,a.d*b.d%mod);
}

/*major*/
void sol(int lx,int rx,int ly,int ry)
{
if(W==1 && H==1) {Single_sol(lx,rx,ly,ry,1);return;}
rx=rx-W+1;ry=ry-H+1;int c=0,L=1;
for(;L<W || L<H;L<<=1) c++;//max( 0^(W-1) | 0^(H-1) ) 共c位 循环节 2^c
Step_sol(lx,rx,ly,ry,0,L-W,0,L-H,c);
for(c++;c<=30;L<<=1,c++){
Step_sol(lx,rx,ly,ry,L-W+1,L-1,0,(L<<1)-H,c);// 0->(L<<1)-H 所有xor <2^(c+1)的数
//L-W+1 -> L-1 注意只能算一次
Step_sol(lx,rx,ly,ry,0,L-W,L-H+1,L-1,c);
Step_sol(lx,rx,ly,ry,L,(L<<1)-W,L-H+1,L-1,c);
}
}

int main(){
int i,j,sz,lx,ly,rx,ry;
for(scanf("%d",&tk);tk;--tk){
a.clear();ans=0;
scanf("%d%d%d%d%d%d%d",&lx,&rx,&ly,&ry,&W,&H,&K);
sol(lx,rx,ly,ry);
sort(a.begin(),a.end());sz=a.size();
for(i=0;i<sz;++i){
if((!i)||(a[i].fi!=a[i-1].fi)) j=fp(a[i].fi%mod,K);