QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#243111 | #4758. Captivating process | serene_analysis | WA | 65ms | 289768kb | C++14 | 6.9kb | 2023-11-07 21:07:27 | 2023-11-07 21:07:28 |
Judging History
answer
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
#include<set>
const int maxn=4e5+5;
const int logn=2e1+5;
int n,m;
struct tree{
std::vector<int>son[maxn];
bool vis[maxn],in[maxn],lop[maxn];
int to[maxn],stk[maxn],scnt,bel[maxn],pid[maxn],up[maxn][logn];
std::vector<int>apr[maxn];
int bcnt;
void go(int x){
// printf("go:%d,to[x]=%d,vis[to]=%d,in[to[x]]=%d\n",x,to[x],vis[to[x]],in[to[x]]);
stk[++scnt]=x,in[x]=true,vis[x]=true;
if(!vis[to[x]])go(to[x]);
else if(in[to[x]]){
bcnt++,stk[scnt+1]=0;
while(stk[scnt+1]!=to[x])bel[stk[scnt]]=bcnt,in[stk[scnt]]=false,lop[stk[scnt]]=true,scnt--;
int p=to[x];
do{
// printf("pid[%d]=%d\n",p,(int)apr[bcnt].size());
pid[p]=apr[bcnt].size(),apr[bcnt].push_back(p),p=to[p];
}while(p!=to[x]);
while(scnt)in[stk[scnt]]=false,scnt--;
}
if(scnt)scnt--,in[x]=false;
return;
}
int d[maxn],size[maxn],dfn[maxn],alt;
int over(int x,int gd){
if(gd>d[x])fprintf(stderr,"shik\n");
for(int i=logn-2;i>=0;i--)if((gd>>i)&1)x=up[x][i];
return x;
}
bool have(int x,int y){return dfn[y]>=dfn[x]&&dfn[y]<=dfn[x]+size[x]-1;}
void divide(int x){
// printf("x=%d,d[x]=%d\n",x,d[x]);
size[x]=1,dfn[x]=++alt;
for(int j=1;j<=logn-2;j++)up[x][j]=up[up[x][j-1]][j-1];
for(int v:son[x]){
if(lop[v])continue;
// printf("x=%d,v=%d\n",x,v);
d[v]=d[x]+1,up[v][0]=x,divide(v),size[x]+=size[v];
}
return;
}
void init(){
for(int i=1;i<=n;i++)scanf("%d",to+i),son[to[i]].push_back(i);
for(int i=1;i<=n;i++)if(!vis[i])go(i);
for(int i=1;i<=n;i++)if(lop[i])divide(i);
return;
}
}ft,st;
struct seg{
int l,r;
friend bool operator<(seg now,seg oth){return now.l==oth.l?now.r<oth.r:now.l<oth.l;}
};
bool can[maxn][3];
struct ques{int wz,id;};
std::vector<ques>fqu[maxn],squ[maxn];
std::set<seg>sapr[maxn];
bool have(int ip,int x){
// if(ip<=0||ip>=maxn)fprintf(stderr,"shik\n");
auto dt=sapr[ip].lower_bound((seg){x+1,0});
if(dt==sapr[ip].begin())return false;
// fprintf(stderr,"have=%d\n",std::prev(dt)->r>=x);
return std::prev(dt)->r>=x;
}
void fgo(int x){
int ip=ft.d[x]-st.d[x]+maxn/2;
// printf("fgo:%d,ip=%d,lin={%d,%d}\n",x,ip,ft.dfn[x],ft.dfn[x]+ft.size[x]-1);
bool ins=false;
if(!have(ip,ft.dfn[x]))ins=true,sapr[ip].insert((seg){ft.dfn[x],ft.dfn[x]+ft.size[x]-1});
// if(x==60){
// printf("x=%d,ft.dfn[x]=%d,st.up[x][0]=%d,ip=%d,ins=%d\n",x,ft.dfn[x],st.up[x][0],ip,ins);
// }
for(ques now:fqu[x]){
// printf("query,now.wz=%d,now.id=%d\n",now.wz,now.id);
can[now.id][0]|=have(ft.d[now.wz]-st.d[x]+maxn/2,ft.dfn[now.wz]);
// if(now.id==4708)printf("can[now.id][0]=%d,ft.dfn[now.wz]=%d\n",can[now.id][0],ft.dfn[now.wz]);
}
for(int v:st.son[x])if(!st.lop[v])fgo(v);
if(ins)sapr[ip].erase((seg){ft.dfn[x],ft.dfn[x]+ft.size[x]-1})/*,printf("ctrl_z:%d\n",x)*/;
return;
}
std::set<int>papr[maxn];
void sgo(int x){
// if(x==11)printf("sgo:%d\n",x);
if(!ft.lop[x]){
// printf("not on loop\n");
for(ques now:squ[x])can[now.id][1]|=papr[ft.bel[now.wz]]
.find((ft.pid[now.wz]+st.d[x])%ft.apr[ft.bel[now.wz]].size())!=papr[ft.bel[now.wz]].end();
for(int v:st.son[x])if(!st.lop[v])sgo(v);
return;
}
bool ins=false;
int ip=(ft.pid[x]+st.d[x])%ft.apr[ft.bel[x]].size();
if(papr[ft.bel[x]].empty()||papr[ft.bel[x]].find(ip)==papr[ft.bel[x]].end())ins=true,papr[ft.bel[x]].insert(ip);
// if(x==3||x==11){
// printf("x=%d,ft.bel[x]=%d,papr[ft.bel[x]].size()=%d,st.up[x][0]=%d,ip=%d,ins=%d\n",
// x,ft.bel[x],(int)papr[ft.bel[x]].size(),st.up[x][0],ip,ins);
// }
for(ques now:squ[x]){
// if(x==40489)printf("now.wz=%d,ft.bel[now.wz]=%d,x=%d,gv=%d\n",now.wz,ft.bel[now.wz],x,
// (int)((ft.pid[now.wz]+st.d[x])%ft.apr[ft.bel[now.wz]].size()));
can[now.id][1]|=papr[ft.bel[now.wz]].find
((ft.pid[now.wz]+st.d[x])%ft.apr[ft.bel[now.wz]].size())!=papr[ft.bel[now.wz]].end();
// if(now.id==2665)printf("can[now.id][1]=%d\n",can[now.id][1]);
}
for(int v:st.son[x])if(!st.lop[v])sgo(v);
if(ins)papr[ft.bel[x]].erase(ip);
return;
}
int qx[maxn],qy[maxn];
int gcd(int a,int b){return b?gcd(b,a%b):a;}
struct pii{
int x,y;
friend bool operator<(pii now,pii oth){return now.x==oth.x?now.y<oth.y:now.x<oth.x;}
};
std::map<pii,bool>apr[maxn];
signed main(){
// freopen("wait.in","r",stdin);
// freopen("wait.out","w",stdout);
scanf("%d%d",&n,&m);
ft.init(),st.init();
// printf("st.lop[11]=%d,st.d[11]=%d,st.up[11][0]=%d\n",st.lop[11],st.d[11],st.up[11][0]);
for(int i=1;i<=n;i++)if(ft.lop[i]&&st.lop[i]){
int fp=ft.bel[i],sp=st.bel[i],d=gcd(ft.apr[fp].size(),st.apr[sp].size());
// if(i==28){
// printf("i=%d,ft.lop&&st.lop\n",i);
// printf("fp=%d,sp=%d,d=%d\n",fp,sp,d);
// }
apr[((ft.pid[i]-st.pid[i])%d+d)%d][{fp,sp}]=true;
}
for(int i=1;i<=m;i++){
scanf("%d%d",qx+i,qy+i),fqu[qy[i]].push_back((ques){qx[i],i});
int fd=ft.d[qx[i]],sd=st.d[qy[i]];
// printf("qx[i]=%d,qy[i]=%d,fd=%d,sd=%d\n",qx[i],qy[i],fd,sd);
// if(i==4708){
// fprintf(stderr,"qx[i]=%d,qy[i]=%d\n",qx[i],qy[i]);
// for(int x=1;x<=n;x++)if(ft.have(x,qx[i])&&st.have(x,qy[i])&&
// ft.d[x]-st.d[x]==ft.d[qx[i]]-st.d[qy[i]])printf("x=%d\n",x);
// int x=qx[i],y=qy[i];
// while(x!=y){
// printf("x=%d,y=%d\n",x,y);
// x=ft.to[x],y=st.to[y];
// }
// printf("ok,x=%d\n",x);
// printf("ok,x=%d,ft.pid[x]=%d,ft.pid[qx[i]]=%d,st.d[qy[i]]=%d,st.d[x]=%d,ft.apr[ft.bel[x]].size()=%d,ans=%d\n",
// x,ft.pid[x],ft.pid[qx[i]],st.d[qy[i]],st.d[x],(int)ft.apr[ft.bel[x]].size(),
// (int)((ft.pid[x]-ft.pid[qx[i]]-st.d[qy[i]]+st.d[x])%ft.apr[ft.bel[x]].size()));
// }
if(fd<=sd){
int x=ft.over(qx[i],fd),y=st.over(qy[i],fd);
squ[y].push_back((ques){x,i});
x=ft.apr[ft.bel[x]][(ft.pid[x]+sd-fd)%ft.apr[ft.bel[x]].size()],y=st.over(y,sd-fd);
int fp=ft.bel[x],sp=st.bel[y],d=gcd(ft.apr[fp].size(),st.apr[sp].size());
can[i][2]|=apr[((ft.pid[x]-st.pid[y])%d+d)%d][{fp,sp}];
}
else{
int x=ft.over(qx[i],fd),y=st.over(qy[i],sd);
y=st.apr[st.bel[y]][(st.pid[y]+fd-sd)%st.apr[st.bel[y]].size()];
int fp=ft.bel[x],sp=st.bel[y],d=gcd(ft.apr[fp].size(),st.apr[sp].size());
can[i][2]|=apr[((ft.pid[x]-st.pid[y])%d+d)%d][{fp,sp}];
}
}
for(int i=1;i<=n;i++)if(st.lop[i])fgo(i),sgo(i);
for(int i=1;i<=n;i++)fqu[i].clear(),squ[i].clear();
// printf("fir,ok\n");
std::swap(ft,st);
for(int i=1;i<=m;i++){
std::swap(qx[i],qy[i]);
int fd=ft.d[qx[i]],sd=st.d[qy[i]];
// printf("qx[i]=%d,qy[i]=%d\n",qx[i],qy[i]);
if(fd<=sd){
int x=ft.over(qx[i],fd),y=st.over(qy[i],fd);
// printf("fd=%d,sd=%d,over,x=%d,y=%d\n",fd,sd,x,y);
squ[y].push_back((ques){x,i});
}
}
for(int i=1;i<=n;i++)if(st.lop[i])sgo(i);
for(int i=1;i<=m;i++){
printf("i=%d\n",i);
printf("%s\n",can[i][0]||can[i][1]||can[i][2]?"YES":"NO");
}
return 0;
}
/*
10 10
7 5 4 7 7 7 3 2 6 7
9 7 7 7 8 1 10 10 1 9
3 8
6 4
8 1
3 8
7 9
6 7
6 6
1 5
10 9
2 7
*/
/*
10 5
1 4 5 8 3 3 2 7 8 1
1 4 5 8 3 3 2 7 8 1
2 3
4 5
6 7
8 9
1 10
*/
//namespace burningContract
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 65ms
memory: 289768kb
input:
3 2 2 3 1 2 3 1 1 2 1 1
output:
i=1 NO i=2 YES
result:
wrong output format YES or NO expected, but I=1 found [1st token]