#include <bits/stdc++.h>
#define DIMN 100010
using namespace std;
int tt[DIMN] , lvl[DIMN] , f[DIMN];
int up[DIMN] , l[DIMN] , d[DIMN] , poz[DIMN];
struct idk{
idk *st , *dr;
short mp[2100];
idk(){
st = dr = 0;
memset (mp , 0 , sizeof(mp));
}
};
idk *aint[DIMN];
vector <int> v[DIMN] , w[DIMN];
int elem , lnt , curr;
void dfs_lant(int nod , int fth){
int i,vecin,ok=0,maxi,fiu;
tt[nod] = fth;
d[nod] = 1;
maxi=0;
fiu=0;
for (i=0;i<v[nod].size();++i){
vecin=v[nod][i];
if (vecin!=fth){
ok=1;
lvl[vecin] = 1 + lvl[nod];
dfs_lant(vecin , nod);
d[nod] += d[vecin];
if (d[vecin]>maxi){
maxi=d[vecin];
fiu=vecin;
}
}
}
if (!ok){ /// frunza
lnt++;
l[nod]=lnt; /// lantul din care apartine
w[lnt].push_back(nod);
}else { /// unim cu poz
w[l[fiu]].push_back(nod);
l[nod]=l[fiu];
for (i=0;i<v[nod].size();++i){
vecin=v[nod][i];
if (vecin!=fth && vecin!=fiu)
up[l[vecin]]=nod; /// din lantul vecinului trecem in lantul nodului
}
}
v[nod].clear();
}
void update_aint (idk *&node , int st , int dr , int l , int r , int len , int val , int sens){
int mid , rest;
if (st == dr){
//if (st == 1 || st == 0)
// printf ("a");
//if (len == 1)
// printf ("a");
node->mp[len * 100 + curr] += val;
curr++;
return;
}
mid=((st+dr)>>1);
if (sens == -1){
if (l <= mid){
if (node->st == NULL){
node->st = new idk;
}
update_aint(node->st , st , mid , l , r , len , val , sens);
}
if (mid + 1 <= r){
if (node->dr == NULL){
node->dr = new idk;
}
update_aint(node->dr , mid + 1 , dr , l , r , len , val , sens);
}
}
else {
if (mid + 1 <= r){
if (node->dr == NULL){
node->dr = new idk;
}
update_aint(node->dr , mid + 1 , dr , l , r , len , val , sens);
}
if (l <= mid){
if (node->st == NULL){
node->st = new idk;
}
update_aint(node->st , st , mid , l , r , len , val , sens);
}
}
for (rest = 0 ; rest < len ; ++rest)
node->mp[len * 100 + rest] = 0;
if (node->st != NULL)
for (rest = 0 ; rest < len ; ++rest)
node->mp[len * 100 + rest] += node->st->mp[len * 100 + rest];
if (node->dr != NULL)
for (rest = 0 ; rest < len ; ++rest)
node->mp[len * 100 + rest] += node->dr->mp[len * 100 + rest];
//if (len == 1 && l == 20)
// printf ("%d %d %d\n",node->mp[100] , st , dr);
}
void update (int x , int y , int len , int val){
if (l[x]!=l[y]){ /// avansam
if (lvl[up[l[x]]]>lvl[up[l[y]]]){
update_aint (aint[l[x]] , 0 , w[l[x]].size()-1 , 0 , poz[x] , len , val , 1);
update ( up[l[x]] , y , len , val);
}
else{
update ( x , up[l[y]] , len , val );
update_aint( aint[l[y]] , 0 , w[l[y]].size()-1 , 0 , poz[y] , len , val , -1 );
}
}
else {
if (poz[x] <= poz[y])
update_aint( aint[l[x]] , 0 , w[l[x]].size()-1 , poz[x] , poz[y] , len , val , -1 );
else
update_aint( aint[l[x]] , 0 , w[l[x]].size()-1 , poz[y] , poz[x] , len , val , 1 );
}
}
long long query_aint (idk *&node , int st , int dr , int px , int py , int t1 , int t2){
int mid , len , rest;
long long sol = 0;
if (px <= st && dr <= py){
for (len = 1 ; len <= 20 ; ++len){
for (rest = 0 ; rest < len ; ++rest){
sol += 1LL * node->mp[len * 100 + rest] * ((t2 / len) + (t2 % len >= rest) - ((t1 - 1) / len) - ((t1 - 1) % len >= rest));
}
}
return sol;
}
mid = ((st + dr)>>1);
if (px <= mid && node->st != NULL)
sol = sol + query_aint(node->st , st , mid , px , py , t1 , t2);
if (mid+1 <= py && node->dr != NULL)
sol = sol + query_aint(node->dr , mid + 1 , dr , px , py , t1 , t2);
return sol;
}
long long query (int x , int y , int t1 , int t2){
if (l[x] != l[y]){ /// avansam
if (lvl[up[l[x]]]>lvl[up[l[y]]])
return query(up[l[x]] , y , t1 , t2) + query_aint(aint[l[x]] , 0 , w[l[x]].size()-1 , 0 , poz[x] , t1 , t2);
else{
//printf ("%d",query_aint(aint[l[y]] , 0 , w[l[y]].size()-1 , 0 , poz[y] , t1 , t2));
return query(x , up[l[y]] , t1 , t2) + query_aint(aint[l[y]] , 0 , w[l[y]].size()-1 , 0 , poz[y] , t1 , t2);
}
}
else{
return query_aint(aint[l[x]] , 0 , w[l[x]].size()-1 , min(poz[x],poz[y]) , max(poz[x],poz[y]) , t1 , t2);
}
}
int adauga (int x , int y){
int nod1 , nod2;
nod1 = x;
nod2 = y;
while (lvl[nod1] > lvl[nod2])
nod1 = tt[nod1];
while (lvl[nod1] < lvl[nod2])
nod2 = tt[nod2];
while (nod1 != nod2){
nod1 = tt[nod1];
nod2 = tt[nod2];
}
return lvl[x] + lvl[y] - 2 * lvl[nod1] + 1;
}
int main()
{
FILE *fin = stdin;
FILE *fout = stdout;
int n , i , x , y , tip , k , q , t1 , t2 , p , vecin , len;
fscanf (fin,"%d",&n);
for (i = 1 ; i < n ; ++i){
fscanf (fin,"%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
lvl[1] = 1;
dfs_lant(1 , 0);
/// fiecare nod al catelea e
for (i=1;i<=lnt;++i){
reverse(w[i].begin(),w[i].end());
p=0;
for (vector <int> :: iterator j=w[i].begin();j!=w[i].end();j++){
/// pozitia lui din lantul curent
vecin=*j;
poz[vecin]=p;
p++;
}
aint[i] = new idk;
}
fscanf (fin,"%d",&k);
for (i = 1 ; i <= k ; ++i){
fscanf (fin,"%d%d",&x,&y);
len = adauga(x , y);
curr = 0;
update(x , y , len , 1);
}
fscanf (fin,"%d",&q);
for (i = 1 ; i <= q ; ++i){
fscanf (fin,"%d",&tip);
if (tip == 1){
fscanf (fin,"%d%d",&x,&y);
len = adauga(x , y);
curr = 0;
update (x , y , len , 1);
}
else if (tip == 2){
fscanf (fin,"%d%d",&x,&y);
len = adauga(x , y);
curr = 0;
update (x , y , len , -1);
}
else {
fscanf (fin,"%d%d%d%d",&x,&y,&t1,&t2);
fprintf (fout,"%lld\n",query (x , y , t1 , t2));
}
}
return 0;
}
Compilation message
traffickers.cpp: In function 'void dfs_lant(int, int)':
traffickers.cpp:23:15: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (i=0;i<v[nod].size();++i){
~^~~~~~~~~~~~~~
traffickers.cpp:43:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (i=0;i<v[nod].size();++i){
~^~~~~~~~~~~~~~
traffickers.cpp: In function 'int main()':
traffickers.cpp:180:12: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d",&n);
~~~~~~~^~~~~~~~~~~~~
traffickers.cpp:182:16: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d%d",&x,&y);
~~~~~~~^~~~~~~~~~~~~~~~~~
traffickers.cpp:204:12: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d",&k);
~~~~~~~^~~~~~~~~~~~~
traffickers.cpp:206:16: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d%d",&x,&y);
~~~~~~~^~~~~~~~~~~~~~~~~~
traffickers.cpp:212:12: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d",&q);
~~~~~~~^~~~~~~~~~~~~
traffickers.cpp:214:16: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d",&tip);
~~~~~~~^~~~~~~~~~~~~~~
traffickers.cpp:216:20: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d%d",&x,&y);
~~~~~~~^~~~~~~~~~~~~~~~~~
traffickers.cpp:222:20: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d%d",&x,&y);
~~~~~~~^~~~~~~~~~~~~~~~~~
traffickers.cpp:228:20: warning: ignoring return value of 'int fscanf(FILE*, const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
fscanf (fin,"%d%d%d%d",&x,&y,&t1,&t2);
~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
5504 KB |
Output is correct |
2 |
Correct |
17 ms |
13312 KB |
Output is correct |
3 |
Correct |
13 ms |
11392 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
108 ms |
77304 KB |
Output is correct |
2 |
Correct |
97 ms |
61432 KB |
Output is correct |
3 |
Correct |
126 ms |
82808 KB |
Output is correct |
4 |
Correct |
109 ms |
74232 KB |
Output is correct |
5 |
Correct |
108 ms |
68600 KB |
Output is correct |
6 |
Correct |
108 ms |
71288 KB |
Output is correct |
7 |
Correct |
133 ms |
73336 KB |
Output is correct |
8 |
Correct |
117 ms |
86648 KB |
Output is correct |
9 |
Correct |
126 ms |
88696 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
975 ms |
217720 KB |
Output is correct |
2 |
Correct |
961 ms |
239356 KB |
Output is correct |
3 |
Correct |
954 ms |
249592 KB |
Output is correct |
4 |
Correct |
864 ms |
194680 KB |
Output is correct |
5 |
Correct |
738 ms |
189400 KB |
Output is correct |
6 |
Correct |
945 ms |
246392 KB |
Output is correct |
7 |
Correct |
929 ms |
258552 KB |
Output is correct |
8 |
Correct |
981 ms |
257912 KB |
Output is correct |