实在是调不动了,小数据根本拍不出来
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std ;
#define int long long
namespace IO {
const int MAXSIZE = 1 << 20;
char buf[MAXSIZE], *p1, *p2;
#define gc() getchar()
//#define gc() \
// (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) \
// ? EOF \
// : *p1++)
inline int rd() {
int x = 0, f = 1;
char c = gc();
while (!isdigit(c)) {
if (c == '-') f = -1;
c = gc();
}
while (isdigit(c)) x = x * 10 + (c ^ 48), c = gc();
return x * f;
}
char pbuf[1 << 20], *pp = pbuf;
inline void push(const char &c) {
if (pp - pbuf == 1 << 20) fwrite(pbuf, 1, 1 << 20, stdout), pp = pbuf;
*pp++ = c;
}
inline void write(int x) {
static int sta[35];
int top = 0;
do {
sta[top++] = x % 10, x /= 10;
} while (x);
while (top) push(sta[--top] + '0');
}
}
using namespace IO ;
//const int N = 500005 , L = 10 , K = 7 , M = 998244353 , O = 1000000007 ;
const int N = 500005 , L = 71 , K = 853 , M = 1e9 + 7 , O = 1e9 + 9 ;
int n , m , q , rt , a[N] , t[N<<2] , e[N<<2] , vl[N] , vk[N] ;
vector < int > vc[N] ;
map < int , int > mp , ap ;
int val[N] , wal[N] ;
void dfs ( int x , int w , int ww ) {
mp [ w ] = x ;
val [ x ] = w ;
ap [ ww ] = x ;
wal [ x ] = ww ;
sort ( vc [ x ] .begin ( ) , vc [ x ] .end ( ) ) ;
int siz = vc [ x ] .size ( ) ;
for ( int i = 0 ; i < siz ; ++ i )
dfs ( vc [ x ] [ i ] , ( w * L + i + 1 ) % M , ( ww * K + i + 1 ) % O ) ;
}
void build ( int k , int l , int r ) {
if ( l == r ) {
t [ k ] = a [ l ] ;
e [ k ] = a [ l ] ;
return ;
}
int mid = ( l + r ) >> 1 ;
build ( k << 1 , l , mid ) ;
build ( k << 1 | 1 , mid + 1 , r ) ;
t [ k ] = ( t [ k << 1 ] * vl [ r - mid ] + t [ k << 1 | 1 ] ) % M ;
e [ k ] = ( e [ k << 1 ] * vk [ r - mid ] + e [ k << 1 | 1 ] ) % O ;
}
int la , lb ;
int query ( int k , int l , int r , int x , int y , int za , int zb ) {
if ( l == r ) {
if ( mp .find ( ( za * L + t [ k ] ) % M ) != mp .end ( ) && ap .find ( ( zb * K + e [ k ] ) % O ) != ap .end ( ) ) {
la = ( za * L + t [ k ] ) % M ;
lb = ( zb * K + e [ k ] ) % O ;
return -1 ;
}
return 1 ;
}
int mid = ( l + r ) >> 1 ;
if ( x <= l && r <= y ) {
if ( mp .find ( ( za * vl [ r - l + 1 ] + t [ k ] ) % M ) != mp .end ( ) && ap .find ( ( zb * vk [ r - l + 1 ] + e [ k ] ) % O ) != ap .end ( ) ) {
la = ( za * vl [ r - l + 1 ] + t [ k ] ) % M ;
lb = ( zb * vk [ r - l + 1 ] + e [ k ] ) % O ;
return -1 ;
}
if ( mp .find ( ( za * vl [ mid - l + 1 ] + t [ k << 1 ] ) % M ) == mp .end ( ) || ap .find ( ( zb * vk [ mid - l + 1 ] + e [ k << 1 ] ) % O ) == ap .end ( ) ) {
return query ( k << 1 , l , mid , x , y , za , zb ) ;
}
la = ( za * vl [ mid - l + 1 ] + t [ k << 1 ] ) % M ;
lb = ( zb * vk [ mid - l + 1 ] + e [ k << 1 ] ) % O ;
return query ( k << 1 | 1 , mid + 1 , r , x , y , la , lb ) ;
}
if ( y <= mid )
return query ( k << 1 , l , mid , x , y , za , zb ) ;
if ( x > mid )
return query ( k << 1 | 1 , mid + 1 , r , x , y , za , zb ) ;
int res = query ( k << 1 , l , mid , x , y , za , zb ) ;
if ( res == -1 )
return query ( k << 1 | 1 , mid + 1 , r , x , y , la , lb ) ;
return res ;
}
void change ( int k , int l , int r , int x , int y ) {
if ( l == r ) {
t [ k ] = y ;
e [ k ] = y ;
return ;
}
int mid = ( l + r ) >> 1 ;
if ( x <= mid )
change ( k << 1 , l , mid , x , y ) ;
else
change ( k << 1 | 1 , mid + 1 , r , x , y ) ;
t [ k ] = ( t [ k << 1 ] * vl [ r - mid ] + t [ k << 1 | 1 ] ) % M ;
e [ k ] = ( e [ k << 1 ] * vk [ r - mid ] + e [ k << 1 | 1 ] ) % O ;
}
signed main ( ) {
n = rd ( ) , m = rd ( ) , q = rd ( ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
int x = rd ( ) ;
if ( x == 0 ) rt = i ;
else vc [ x ] .push_back ( i ) ;
}
dfs ( rt , 0 , 0 ) ;
vl [ 0 ] = 1 ;
vk [ 0 ] = 1 ;
for ( int i = 1 ; i <= m ; ++ i )
a [ i ] = rd ( ) , vl [ i ] = vl [ i - 1 ] * L % M , vk [ i ] = vk [ i - 1 ] * K % O ;
build ( 1 , 1 , m ) ;
for ( int i = 1 ; i <= q ; ++ i ) {
int op = rd ( ) , x = rd ( ) , y = rd ( ) ;
if ( op == 1 ) {
int z = rd ( ) ;
la = val [ x ] ;
lb = wal [ x ] ;
query ( 1 , 1 , m , y , z , val [ x ] , wal [ x ] ) ;
cout << mp [ la ] << "\n" ;
} else {
change ( 1 , 1 , m , x , y ) ;
a [ x ] = y ;
}
}
return 0 ;
}