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 cities, numbered by the first uppercase letters, for example the first city named , 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 soldiers to walk between these cities. The soldiers are numbered from to . I will tell you the initial position of each soldier, and then issue three types of orders:
Interval Move: Given two integers and , 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 , the soldiers whose number is a multiple of (id mod ) do Moving Operation.
Commander Report: Given an integer , 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
and
, which represent the amounts of city and soldier.
The second line is a -length string. The letter in the string represents the directed road’s leading city from the city. It’s guaranteed that the letter in the string differs from the letter in the alphabet, and the string only consists of uppercase letters.
The third line is a -length string. The letter in the string represents the soldier’s initial city. The string also only consists of uppercase letters.
The fourth line consists of an integer , which represent the number of king’s orders.
Following lines, the first part of the line is an integer .
If , then input two integers and , which represent the soldiers numbered between do Moving Operation.
If , then input an integer , which represents the soldiers whose number is a multiple of do Moving Operation.
If , then input an integer , you should output where the soldier numbered located in.
Its guaranteed there is at least one order that .
Output
For each order that
, 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;
}