Advertisement
Guest User

1957F1 - Frequency Mismatch (Easy Version)

a guest
Apr 25th, 2024
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.50 KB | Source Code | 0 0
  1. #pragma GCC optimize("Ofast")
  2. #include <bits/stdc++.h>
  3. #define ff first
  4. #define ss second
  5. using namespace std;
  6. typedef long long ll;
  7.  
  8. const int N = 2e5+5, LOG = 17, MOD = 1000000007;
  9. mt19937 eng{std::random_device{}()};
  10.  
  11. int rnd(){
  12.     uniform_int_distribution<int> uid(0, MOD-1);
  13.     return uid(eng) % MOD;
  14. }
  15.  
  16. const int R = rnd();
  17.  
  18. long long power(long long a, long long b, long long m=MOD) {
  19.     a %= m;
  20.     long long res = 1;
  21.     while (b > 0) {
  22.         if (b & 1)
  23.             res = res * a % m;
  24.         a = a * a % m;
  25.         b >>= 1;
  26.     }
  27.     return res % m;
  28. }
  29.  
  30. int inv(int a){
  31.     return power(a,MOD-2);
  32. }
  33.  
  34. int n,q,k,ar[N],st[N],en[N],ord[N],d[N],p[LOG][N],cnt;
  35. vector<vector<int> > e;
  36. vector<int> res;
  37.  
  38. void dfs(int node,int prnt){
  39.     st[node] = ++cnt;
  40.     ord[cnt] = node;
  41.     p[0][node] = prnt;
  42.     for(int i = 1;i<LOG;i++){
  43.         p[i][node] = p[i-1][p[i-1][node]];
  44.     }
  45.     for(auto nxt:e[node]){
  46.         if(nxt == prnt)
  47.             continue;
  48.         d[nxt] = d[node] + 1;
  49.         dfs(nxt,node);
  50.     }
  51.     en[node] = ++cnt;
  52.     ord[cnt] = node;
  53. }
  54. int getKth(int a,int K){
  55.     for(int i = 0;i<LOG;i++){
  56.         if((1<<i) & K){
  57.             a = p[i][a];
  58.         }
  59.     }
  60.     return a;
  61. }
  62. int LCA(int a,int b){
  63.     if(d[a] < d[b])
  64.         swap(a,b);
  65.     a = getKth(a,d[a]-d[b]);
  66.     if(a == b)
  67.         return a;
  68.     for(int i = LOG-1;i>=0;i--){
  69.         if(p[i][a] != p[i][b]){
  70.             a = p[i][a];
  71.             b = p[i][b];
  72.         }
  73.     }
  74.     return p[0][a];
  75. }
  76.  
  77. extern struct Node *EMPTY;
  78.  
  79. struct Node{
  80.     ll mul;
  81.     Node *lt,*rt;
  82.     Node(){
  83.         lt = this;
  84.         rt = this;
  85.         mul = 1LL;
  86.     }
  87.     Node(ll mull,Node *ltt = EMPTY,Node *rtt = EMPTY){
  88.         mul  = mull;
  89.         lt = ltt;
  90.         rt = rtt;
  91.     }
  92.     // Node():lt(this),rt(this),mul(1LL){}
  93.     // Node(ll mul,Node *lt = EMPTY, Node *rt = EMPTY):mul(mul),lt(lt),rt(rt){}
  94. };
  95. Node *EMPTY = new Node();
  96. Node *roots[N];
  97.  
  98. Node *insert(int val,Node *cur,int neg = 0,int l = 1,int r = 1e5){
  99.     if(val > r || val < l)
  100.         return cur;
  101.     if(l == r){
  102.         if(neg){
  103.             return new Node(cur->mul * inv((R + val + 0LL) % MOD) % MOD);
  104.         }
  105.         return new Node(cur->mul * ((R + val + 0LL) % MOD) % MOD);
  106.     }
  107.     int md = (l+r)/2;
  108.     Node *LT = insert(val,cur->lt,neg,l,md);
  109.     Node *RT = insert(val,cur->rt,neg,md+1,r);
  110.     return new Node(LT->mul * RT->mul % MOD,LT,RT);
  111. }
  112.  
  113. ll calcMul(Node *lft,Node *rgt){
  114.     return rgt->mul * inv(lft->mul) % MOD;
  115. }
  116. ll calcMul(Node *downLft1,Node *downRgt1,Node *upLft1,Node *upRgt1,ll lca1,int l,int r){
  117.     ll mul = inv(calcMul(downLft1,downRgt1)) * calcMul(upLft1,upRgt1) % MOD;
  118.     if(lca1 >= l && lca1 <= r){
  119.         // cout<<"H"<<lca1<<"H ";
  120.         mul = mul * ((lca1 + R + 0LL) % MOD) % MOD;
  121.     }
  122.     return mul;
  123. }
  124.  
  125. void traverse(Node *cur,int l = 1,int r = 1e5){
  126.     cout<<l<<" "<<r<<" "<<cur->mul<<endl;
  127.     if(l == r){
  128.         return;
  129.     }    
  130.     int md = (l+r)/2;
  131.     traverse(cur->lt,l,md);
  132.     traverse(cur->rt,md+1,r);
  133. }
  134. void print(){
  135.     for(int i = 0;i<=cnt;i++){
  136.         cout<<i<<":\n";
  137.         traverse(roots[i]);
  138.         cout<<endl;
  139.     }
  140. }
  141. void query(Node *downLft1,Node *downLft2,Node *downRgt1,Node *downRgt2,Node *upLft1,Node *upLft2,Node *upRgt1,Node *upRgt2,ll lca1,ll lca2,int l = 1,int r = 1e5){
  142.     if(l == r){
  143.         res.push_back(l);
  144.         return;
  145.     }
  146.     int md = (l + r) / 2;
  147.     ll frstMul = calcMul(downLft1->lt,downRgt1->lt,upLft1->lt,upRgt1->lt,lca1,l,md);
  148.     ll scndMul = calcMul(downLft2->lt,downRgt2->lt,upLft2->lt,upRgt2->lt,lca2,l,md);
  149.     // cout<<l<<" "<<r<<" "<<md<<" :1: "<<frstMul<<" "<<scndMul<<endl;
  150.     if(frstMul != scndMul){
  151.         query(downLft1->lt,downLft2->lt,downRgt1->lt,downRgt2->lt,upLft1->lt,upLft2->lt,upRgt1->lt,upRgt2->lt,lca1,lca2,l,md);
  152.     }
  153.     if(res.size() == k)
  154.         return;
  155.     frstMul = calcMul(downLft1->rt,downRgt1->rt,upLft1->rt,upRgt1->rt,lca1,md+1,r);
  156.     scndMul = calcMul(downLft2->rt,downRgt2->rt,upLft2->rt,upRgt2->rt,lca2,md+1,r);
  157.     // cout<<l<<" "<<r<<" "<<md<<" :2: "<<frstMul<<" "<<scndMul<<endl;
  158.     if(frstMul != scndMul){
  159.         query(downLft1->rt,downLft2->rt,downRgt1->rt,downRgt2->rt,upLft1->rt,upLft2->rt,upRgt1->rt,upRgt2->rt,lca1,lca2,md+1,r);
  160.     }
  161. }
  162.  
  163. int main(){
  164.  
  165.     // freopen("in.txt","r",stdin);
  166.     scanf("%d",&n);
  167.     for(int i = 1;i<=n;i++){
  168.         scanf("%d",&ar[i]);
  169.     }
  170.     e.clear();
  171.     e.resize(n+1);
  172.     for(int i = 0;i<n-1;i++){
  173.         int u,v;
  174.         scanf("%d%d",&u,&v);
  175.         e[u].push_back(v);
  176.         e[v].push_back(u);
  177.     }
  178.     d[1] = 0;
  179.     cnt = 0;
  180.     dfs(1,0);
  181.     roots[0] = EMPTY;
  182.     assert(cnt == 2*n);
  183.     for(int i = 1;i<=cnt;i++){
  184.         if(i > st[ord[i]])
  185.             roots[i] = insert(ar[ord[i]],roots[i-1],1);
  186.         else
  187.             roots[i] = insert(ar[ord[i]],roots[i-1]);
  188.     }
  189.     // print();
  190.     scanf("%d",&q);
  191.     for(int testCase = 1;testCase<=q;testCase++){
  192.         int u1,v1,u2,v2;
  193.         scanf("%d%d%d%d%d",&u1,&v1,&u2,&v2,&k);
  194.         if(st[u1] > st[v1])
  195.             swap(u1,v1);
  196.         if(st[u2] > st[v2])
  197.             swap(u2,v2);
  198.         int lca1 = LCA(u1,v1),oneDown = getKth(u1,d[u1] - d[lca1] - 1),oneUp = getKth(v1,d[v1] - d[lca1] - 1);
  199.         int lca2 = LCA(u2,v2),twoDown = getKth(u2,d[u2] - d[lca2] - 1),twoUp = getKth(v2,d[v2] - d[lca2] - 1);
  200.         assert(lca1 >= 1 && lca1 <= n);
  201.         assert(lca2 >= 1 && lca2 <= n);
  202.         int lftDown1 = en[u1] - 1,rgtDown1,lftDown2 = en[u2]-1,rgtDown2;
  203.         if(u1 == lca1){
  204.             lftDown1 = st[u1] + 1;
  205.             rgtDown1 = lftDown1 - 1;
  206.         }else{
  207.             rgtDown1 = en[oneDown];
  208.         }
  209.         if(u2 == lca2){
  210.             rgtDown2 = en[u2] - 2;
  211.         }else{
  212.             rgtDown2 = en[twoDown];
  213.         }
  214.         int lftUp1,rgtUp1 = st[v1],lftUp2,rgtUp2 = st[v2];
  215.         if(v1 == lca1){
  216.             lftUp1 = st[v1] + 1;
  217.         }else{
  218.             lftUp1 = st[oneUp] - 1;
  219.         }
  220.         if(v2 == lca2){
  221.             lftUp2 = st[v2] + 1;
  222.         }else{
  223.             lftUp2 = st[twoUp] - 1;
  224.         }
  225.         // cout<<u1<<" "<<v1<<" "<<lca1<<" "<<u2<<" "<<v2<<" "<<lca2<<endl;
  226.         // cout<<lftDown1<<" "<<rgtDown1<<" "<<lftDown2<<" "<<rgtDown2<<endl;
  227.         // cout<<lftUp1<<" "<<rgtUp1<<" "<<lftUp2<<" "<<rgtUp2<<endl;
  228.         // cout<<endl;
  229.         Node *downLft1,*downLft2,*downRgt1,*downRgt2,*upLft1,*upLft2,*upRgt1,*upRgt2;
  230.         if(lftDown1 <= rgtDown1){
  231.             downLft1 = roots[lftDown1];
  232.             downRgt1 = roots[rgtDown1];
  233.         }else{
  234.             downLft1 = EMPTY;
  235.             downRgt1 = EMPTY;
  236.         }
  237.         if(lftDown2 <= rgtDown2){
  238.             downLft2 = roots[lftDown2];
  239.             downRgt2 = roots[rgtDown2];
  240.         }else{
  241.             downLft2 = EMPTY;
  242.             downRgt2 = EMPTY;
  243.         }
  244.  
  245.         if(lftUp1 <= rgtUp1){
  246.             upLft1 = roots[lftUp1];
  247.             upRgt1 = roots[rgtUp1];
  248.         }else{
  249.             upLft1 = EMPTY;
  250.             upRgt1 = EMPTY;
  251.         }
  252.         if(lftUp2 <= rgtUp2){
  253.             upLft2 = roots[lftUp2];
  254.             upRgt2 = roots[rgtUp2];
  255.         }else{
  256.             upLft2 = EMPTY;
  257.             upRgt2 = EMPTY;
  258.         }
  259.         res.clear();
  260.         query(downLft1,downLft2,downRgt1,downRgt2,upLft1,upLft2,upRgt1,upRgt2,ar[lca1],ar[lca2]);
  261.         // cout<<"Test Case: #"<<testCase<<" "<<res.size();
  262.         printf("%d",res.size());
  263.         for(auto x:res){
  264.             printf(" %d",x);
  265.         }
  266.         puts("");
  267.     }
  268.     return 0;
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement