Pagini recente » Cod sursa (job #1084690) | Cod sursa (job #366123) | Cod sursa (job #2302009) | Cod sursa (job #107381) | Cod sursa (job #1501011)
#include<cstdio>
#include<bitset>
#define S 1000010
#define N 100010
#define B 330
using namespace std;
int left[N+1];
int right[N+1];
int v[N+1];
int bonus[N+1];
int n;
int lst[N+1];
int urm[2*N+1];
int vecin[2*N+1];
bool viz[N+1];
int k;
int min(int a,int b){
return (a<b) ? a : b;
}
class mazi{
private:
bitset <S+1> sum;
int st,dr;
int add;
public:
void init(int i){
st=(i-1)*B+1;
dr=min(i*B,n);
add=0;
sum[0]=true;
}
void clear(int s){
sum[s]=false;
}
void Add(int s){
add+=s;
}
void update(){
int i;
for(i=st;i<=dr;i++)
if (bonus[i]<S) sum[bonus[i]]=true;
}
int getLeft(){
return st;
}
int getRight(){
return dr;
}
bool isTrue (int s){
if (s-add<0) return false;
else return sum[s-add];
}
int find(int s){
int i;
for(i=st;i<=dr;i++)
if (bonus[i]==s-add) return v[i];
return -1;
}
};
mazi b[N/B+2];
void initializare(){
int i;
for(i=1;i<=(n-1)/B+1;i++){
b[i].init(i);
}
}
void update(int nod,int s){
int st=left[nod];
int dr=right[nod];
int i,lim;
if ((dr-1)/B+1-((st-1)/B+1)<=1){
for(i=st;i<=dr;i++){
b[(i-1)/B+1].clear(bonus[i]);
bonus[i]+=s;
}
b[(st-1)/B+1].update();
if ((dr-1)/B+1!=(st-1)/B+1) b[(dr-1)/B+1].update();
}
else {
lim=b[(st-1)/B+1].getRight();
for(i=st;i<=lim;i++){
b[(st-1)/B+1].clear(bonus[i]);
bonus[i]+=s;
}
b[(st-1)/B+1].update();
for(i=b[(dr-1)/B+1].getLeft();i<=dr;i++){
b[(dr-1)/B+1].clear(bonus[i]);
bonus[i]+=s;
}
b[(dr-1)/B+1].update();
lim=(dr-1)/B;
for(i=(st-1)/B+2;i<=lim;i++)
b[i].Add(s);
}
}
int query(int s){
int i;
for(i=1;i<=(n-1)/B+1;i++){
if (b[i].isTrue(s)) return b[i].find(s);
}
return -1;
}
void adauga(int lista,int nod){
k++;
vecin[k]=nod;
urm[k]=lst[lista];
lst[lista]=k;
}
void parc(int nod=1){
int p;
viz[nod]=true;
n++;
v[n]=nod;
left[nod]=n;
p=lst[nod];
while(p>0){
if (viz[vecin[p]]==false) parc(vecin[p]);
p=urm[p];
}
right[nod]=n;
}
int main(){
freopen ("arbore.in","r",stdin);
freopen ("arbore.out","w",stdout);
int i,m,n1,n2,op;
scanf ("%d%d",&n,&m);
for(i=1;i<n;i++){
scanf ("%d%d",&n1,&n2);
adauga(n1,n2);
adauga(n2,n1);
}
n=0;
parc();
initializare();
for(i=1;i<=m;i++){
scanf ("%d",&op);
if (op==1){
scanf ("%d%d",&n1,&n2);
update(n1,n2);
}
else {
scanf ("%d",&n1);
printf ("%d\n",query(n1));
}
}
return 0;
}