# 2020牛客暑期多校训练营（第七场）J.Pointer Analysis

## 题目描述

Pointer analysis, which aims to figure out which objects accessible via a specific pointer variable in a program during the execution, is one of the fundamental parts of static program analysis. Now we want you to perform the context-insensitive pointer analysis on the test data.

A program contains 26 objects denoted by lowercase letters and each object has 26 member variables (a.k.a. fields, which are pointers that may point to some objects) denoted by lowercase letters as well. Meanwhile, there are 26 global pointers in the programs designated by uppercase letters.

There are four kinds of statements in a program. We use [Variable] to represent the name of a pointer, [Field] to represent the name of a member variable, and [Object] to represent an object.

FormatExampleDescription
Allocation[Variable] = [Object]A = xpointer A can point to object x (i.e., x is accessible via A)
Assignment[Variable] = [Variable]A = Bpointer A can point to every object accessible via B
Store[Variable].[Field] = [Variable]A.f = Bfor every object o accessible via A, the member variable f of o can point to every object accesible via B
Load[Variable] = [Variable].[Field]A = B.ffor every object o accessible via B, A can point to every object accessible via the member variable f of o

The context-insensitive pointer analysis assumes that statements of the program will be executed in any order for a sufficient number of times. For example, in the following two programs, both A and B can point to the object x and object o. The reason for that is, in the real world, the exact execution order and execution times of statements are difficult to predict.

First ProgramSecond Program
A = o A = x B = AB = A A = x A = o

Now you are asked to perform a context-insensitive pointer analysis on a given program consists of N statements, and for each pointer, output the objects it can point to.

## 输入描述:

The first line of the input contains one integer N ( 1 ≤ N ≤ 200 ) N (1 \le N \le 200) , representing the number of statements in the program. There is exactly one space before and after the equal sign ‘=’.

Each of the following N lines contains one statement.

## 输出描述:

The output should contains 26 lines.

In the i-th line, output the name of the i-th pointer (which is the i-th uppercase letter) followed by a colon ‘:’ and a space, and then list the objects accessible via this pointer in alphabetical order.

## 示例1

### 输入

5
B.f = A
C = B.f
C = x
A = o
B = o


### 输出

A: o
B: o
C: ox
D:
E:
F:
G:
H:
I:
J:
K:
L:
M:
N:
O:
P:
Q:
R:
S:
T:
U:
V:
W:
X:
Y:
Z:


## 示例2

### 输入

4
A = o
B.f = A
C = B.f
C = g


### 输出

A: o
B:
C: g
D:
E:
F:
G:
H:
I:
J:
K:
L:
M:
N:
O:
P:
Q:
R:
S:
T:
U:
V:
W:
X:
Y:
Z:


## 示例3

### 输入

3
A = o
B = A
A = x


### 输出

A: ox
B: ox
C:
D:
E:
F:
G:
H:
I:
J:
K:
L:
M:
N:
O:
P:
Q:
R:
S:
T:
U:
V:
W:
X:
Y:
Z:


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
string s1,s2;
char a,b,c;
set<char>ans,object;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>s1[i]>>c>>s2[i];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a=s1[j]-'A',b=s2[j]-'A';
if(s1[j].size()==1&&s2[j].size()==1){
if(islower(s2[j])) ans[a].insert(s2[j]);
else{
for(auto k:ans[b]) if(ans[a].find(k)==ans[a].end()) ans[a].insert(k);
}
}else if(s1[j].size()==3){
c=s1[j]-'a';
for(auto k:ans[a]){
for(auto l:ans[b])
object[k-'a'][c].insert(l);
}
}else{
c=s2[j]-'a';
for(auto k:ans[b]){
for(auto l:object[k-'a'][c])
ans[a].insert(l);
}
}
}
}
for(int i=0;i<26;i++){
cout<<char(i+'A')<<": ";
for(auto j:ans[i]) cout<<j;
cout<<"\n";
}
}

08-06 54
08-02 72 08-01 929
08-01 453
08-09 69
08-02 134
08-02 67
08-03 51
08-02 51
09-16 90