日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ACM-ICPC 2018 徐州赛区网络预赛 I. query 树状数组

發布時間:2023/12/18 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ACM-ICPC 2018 徐州赛区网络预赛 I. query 树状数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

I. query

題目鏈接:

Problem Description

Given a permutation \(p\) of length \(n\), you are asked to answer \(m\) queries, each query can be represented as a pair \((l ,r )\), you need to find the number of pair \((i ,j)\) such that \(l \le i < j \le r\) and \(\min(p_i,p_j) = \gcd(p_i,p_j )\).

Input

There is two integers \(n(1 \le n \le 10^5)\), \(m(1 \le m \le 10^5)\) in the first line, denoting the length of \(p\) and the number of queries.

In the second line, there is a permutation of length \(n\), denoting the given permutation \(p\). It is guaranteed that \(p\) is a permutation of length \(n\).

For the next \(m\) lines, each line contains two integer \(l_i\) and \(r_i(1 \le l_i \le r_i \le n)\), denoting each query.

Output

For each query, print a single line containing only one integer which denotes the number of pair \((i,j)\).

樣例輸入

3 2
1 2 3
1 3
2 3

樣例輸出

2
0

題意

給你一個序列,求很多段子區間\((l ,r )\)滿足\(l \le i < j \le r\) and \(\min(p_i,p_j) = \gcd(p_i,p_j )\) 的個數。

題解

1.轉化一下就是求一個區間有多少對滿足一個是另一個的倍數。

2.我們會發現這個是一個排列,每個數x的倍數個數為\(\frac{n}{x}\),那么所有的倍數個數即為\(\sum_{i=1}^{n}\frac{n}{i})(\le nlog_{2}{n+1})\)

3.我們將所有倍數點對預處理出來,問題就變成了問一個區間有多少倍數點對同時存在。

4.是不是很熟悉啦(不知道也沒關系),我來細細講解一下:

  • 先將區間按右端點從小到大排序,保證右端點單調遞增
  • 那么起作用的就是左端點,這是我們碰到一個點就將它左邊的所有是它約數以及倍數的位置權值全部+1,這樣如果左邊這個點在區間里,右端點必然也在區間里因為右端點單調遞增。

如果真的理解了的話想想按左端點從大到小也可以做,想想怎么做?

其實這題是cf原題,網絡賽時我不會做,然后竟然搜到了原題(還是有極其微小的差異),然后現學啦,哈哈哈。

cf鏈接:codeforces 301D

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define INF 0x7f7f7f7f #define N 100050 template<typename T>void read(T&x) {ll k=0; char c=getchar();x=0;while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();if (c==EOF)exit(0);while(isdigit(c))x=x*10+c-'0',c=getchar();x=k?-x:x; } void read_char(char &c) {while(!isalpha(c=getchar())&&c!=EOF);} int n,m,a[N],p[N],c[N],ans[N]; vector<int>vec[N]; struct Query {int l,r,id;bool operator <(const Query b)const{return r<b.r;} }que[N]; void change(int x){while(x<=n)c[x]++,x+=x&-x;} int ask(int x){int ans=0;while(x)ans+=c[x],x-=x&-x;return ans;} void work() {read(n); read(m);for(int i=1;i<=n;i++) read(a[i]),p[a[i]]=i;for(int i=1;i<=m;i++) read(que[i].l),read(que[i].r),que[i].id=i;for(int i=1;i<=n;i++){for(int j=a[i]+a[i];j<=n;j+=a[i])if (i<p[j])vec[p[j]].push_back(i);else vec[i].push_back(p[j]);}sort(que+1,que+m+1);int r=0;for(int i=1;i<=m;i++){for(int j=r+1;j<=que[i].r;j++)for(int k=0;k<vec[j].size();k++)change(vec[j][k]);r=que[i].r;ans[que[i].id]=ask(que[i].r)-ask(que[i].l-1);}for(int i=1;i<=m;i++)printf("%d\n",ans[i]); } int main() { #ifndef ONLINE_JUDGEfreopen("aa.in","r",stdin); #endifwork(); }

轉載于:https://www.cnblogs.com/mmmqqdd/p/11508422.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的ACM-ICPC 2018 徐州赛区网络预赛 I. query 树状数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。