Letter Kingdom
Time Limit: 2000 MS Memory Limit: 256 MB
One day, you had a dream. In the dream, you got trapped in the Letter Kingdom. Two soldiers caught you, and brought you to the front of the king.
The king asked you: “Are you a programmer?”
You answered: “Yes.”
The king said: Our Letter Kingdom is going to hold the 233rd National Day ceremony, now we need to check our traffic network, and I appoint you to be the commander of this event. Our country has n n cities, numbered by the first uppercase letters, for example the first city named A A , the second city named , and so on. Due to the lack of money, every city only has one directed road to another city. The army will arrange for m m soldiers to walk between these cities. The soldiers are numbered from to m m . I will tell you the initial position of each soldier, and then issue three types of orders:
Interval Move: Given two integers and r r , the soldiers numbered between walk along the only directed road from the current city to another city (we’ll call it Moving Operation).
Multiple Move: Given an integer x x , the soldiers whose number is a multiple of (id mod x=0 x = 0 ) do Moving Operation.
Commander Report: Given an integer p p , please tell me which city the soldier numbered located in.
Since you are a smart person, can you complete this task?
Input
The first line consists of two integers
n
n
and , which represent the amounts of city and soldier.
The second line is a n n -length string. The letter in the string represents the directed road’s leading city from the ith i t h city. It’s guaranteed that the ith i t h letter in the string differs from the ith i t h letter in the alphabet, and the string only consists of uppercase letters.
The third line is a m m -length string. The letter in the string represents the ith i t h soldier’s initial city. The string also only consists of uppercase letters.
The fourth line consists of an integer q q , which represent the number of king’s orders.
Following lines, the first part of the line is an integer op o p .
If op=1 o p = 1 , then input two integers l l and , which represent the soldiers numbered between [l,r] [ l , r ] do Moving Operation.
If op=2 o p = 2 , then input an integer x x , which represents the soldiers whose number is a multiple of do Moving Operation.
If op=3 o p = 3 , then input an integer p p , you should output where the soldier numbered located in.
Its guaranteed there is at least one order that op=3 o p = 3 .
1≤n≤26
1
≤
n
≤
26
1≤m≤200000
1
≤
m
≤
200000
1≤q≤200000
1
≤
q
≤
200000
Output
For each order that
op=3
o
p
=
3
, output the position of the soldier.
Sample input and output
Sample Input
5 6
DAEEA
AEDCBA
7
1 1 4
2 2
3 4
2 3
1 3 6
2 1
3 6
Sample Output
A
D
思路:因为最多只有26个城市,且每个城市有且仅有一条向其它城市连接的道路,所以从任意一个城市开始出发,沿着道路行走,最后都会走进一个环。
于是可以先DFS,对于任意一个作为起点的城市,预处理出它走进的环的大小cyl[i],和走进环需要的距离first[i],以及走step步到达的城市nex[i][step]。
对于士兵行走步数的区间更新和倍数更新。
操作1区间更新可以用树状数组或线段树记录士兵的行走步数。
至于操作2倍数更新,对于某次更新x,用lazy数组存储,即lazy[x]++,表示x的倍数的行走步数需要+1。
查询的时候,用树状数组或线段树求出操作1的步数。
用sqrt(x)的方法枚举x的因子,统计操作2的步数。
求出了士兵x走的总步数后,利用DFS预处理出的信息即可求出答案。
#include<bits/stdc++.h>
using namespace std;
const int MAX=2e5+10;
const int MOD=1e9+7;
const double PI=acos(-1.0);
typedef long long ll;
struct lenka
{
int l,r,sum;
}A[MAX<<2];
void build(int k,int l,int r)
{
A[k].l=l,A[k].r=r;
A[k].sum=0;
if(l==r)return;
build(2*k,l,(l+r)/2);
build(2*k+1,(l+r)/2+1,r);
}
void add(int k,int x,int y,int z)
{
if(x==A[k].l&&y==A[k].r){A[k].sum+=z;return;}
if(A[k].sum!=0)
{
add(2*k,A[2*k].l,A[2*k].r,A[k].sum);
add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].sum);
A[k].sum=0;
}
if(y<=A[2*k].r)add(2*k,x,y,z);
else if(x>=A[2*k+1].l)add(2*k+1,x,y,z);
else
{
add(2*k,x,A[2*k].r,z);
add(2*k+1,A[2*k+1].l,y,z);
}
}
int ask(int k,int x)
{
if(x==A[k].l&&x==A[k].r)return A[k].sum;
if(A[k].sum!=0)
{
add(2*k,A[2*k].l,A[2*k].r,A[k].sum);
add(2*k+1,A[2*k+1].l,A[2*k+1].r,A[k].sum);
A[k].sum=0;
}
if(x<=A[2*k].r)return ask(2*k,x);
return ask(2*k+1,x);
}
int e[30][30];
int first[30];
int cyl[30];
int nex[30][30];
int v[30];
int n;
void dfs(int k,int step,int fa)
{
nex[fa][step]=k;
for(int i=1;i<=n;i++)
{
if(e[k][i]==0)continue;
if(v[i])
{
cyl[fa]=v[k]-v[i]+1;
first[fa]=v[i]-1;
return;
}
v[i]=v[k]+1;
dfs(i,step+1,fa);
}
}
int st[MAX];
char s[MAX];
int lazy[MAX];
int main()
{
int m;
cin>>n>>m;
scanf("%s",s+1);
for(int i=1;i<=n;i++)e[i][s[i]-'A'+1]=1;
for(int i=1;i<=n;i++)
{
memset(v,0,sizeof v);
v[i]=1;
dfs(i,0,i);
}
scanf("%s",s+1);
for(int i=1;i<=m;i++)st[i]=s[i]-'A'+1;
build(1,1,m);
int T;
cin>>T;
while(T--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int x,y;
scanf("%d%d",&x,&y);
add(1,x,y,1);
}
if(op==2)
{
int x;
scanf("%d",&x);
lazy[x]++;
}
if(op==3)
{
int x;
scanf("%d",&x);
int tot=ask(1,x);
for(int i=1;i*i<=x;i++)
{
if(x%i==0)
{
tot+=lazy[i];
if(x%(x/i)==0&&x!=i*i)tot+=lazy[x/i];
}
}
if(tot>first[st[x]])
{
tot-=first[st[x]];
tot%=cyl[st[x]];
tot+=first[st[x]];
}
tot=nex[st[x]][tot];
printf("%c\n",tot+'A'-1);
}
}
return 0;
}