Time complexity 算法何时可以具有平方根(n)时间复杂度?

Time complexity 算法何时可以具有平方根(n)时间复杂度?,time-complexity,Time Complexity,有人能给我举一个时间复杂度为平方根(n)的算法的例子吗。平方根时间复杂性到底意味着什么?有很多情况。 这些是可以在根(n)复杂性中解决的少数问题[也可能更好] 找出一个数是否为素数 Grover的算法:允许(在量子上下文中)在与输入大小平方根成比例的时间内搜索未排序的输入 数字的因式分解 您将面临许多问题,需要使用sqrt(n)复杂度算法 作为对第二部分的答复: sqrt(n)复杂度意味着如果算法的输入大小为n,则大约有sqrt(n)基本操作(如排序时的**比较**)。那么我们可以说该算法具

有人能给我举一个时间复杂度为平方根(n)的算法的例子吗。平方根时间复杂性到底意味着什么?

有很多情况。 这些是可以在根(n)复杂性中解决的少数问题[也可能更好]

  • 找出一个数是否为素数
  • Grover的算法:允许(在量子上下文中)在与输入大小平方根成比例的时间内搜索未排序的输入
  • 数字的因式分解
您将面临许多问题,需要使用
sqrt(n)
复杂度算法

作为对第二部分的答复: sqrt(n)复杂度意味着
如果算法的输入大小为n,则大约有sqrt(n)基本操作(如排序时的**比较**)。那么我们可以说该算法具有sqrt(n)时间复杂度。

让我们来分析第三个问题,它将是明确的

let's n= positive integer. Now there exists 2 positive integer x and y such that
     x*y=n;
     Now we know that whatever be the value of x and y one of them will be less than sqrt(n). As if both are greater than sqrt(n) 
  x>sqrt(n) y>sqrt(n) then x*y>sqrt(n)*sqrt(n) => n>n--->contradiction.
因此,如果我们将2检查为sqrt(n),那么我们将考虑所有因素(1和n是微不足道的因素)

代码段:
intn;
cin>>n;
打印1,n;
对于(int i=2;i
  • 平方根时间复杂度意味着算法需要
    O(N^(1/2))
    求值,其中输入的大小为N
  • 作为一个需要
    O(sqrt(n))
    时间的算法的例子,Grover的算法就是一个需要那么多时间的算法。它是一种量子算法,用于搜索
    O(sqrt(n))
    时间中n个条目的未排序数据库
  • 让我们举一个例子来理解在给定一个问题的情况下,我们如何达到运行时的复杂性。这将是详细的,但理解起来很有趣。(下面的例子,在回答这个问题的上下文中,取自,非常有趣的问题和达到
    O(sqrt)的有趣技巧(n) )
    复杂性)

    • 给定一个包含n个元素的数组,实现点更新和范围和查询的数据结构

      • 更新(i,x)->A[i]:=x(点更新查询)
      • 查询(lo,hi)->返回[lo]+A[lo+1]+..+A[hi]。(范围和查询)
    • 简单的解决方案使用数组。更新(数组索引访问)需要
      O(1)
      时间,范围和(从开始索引到结束索引迭代并相加)需要
      O(hi-lo)=O(n)

    • 更有效的解决方案是将数组拆分为长度为k的片,并将片和存储在数组S中
    • 更新需要固定的时间,因为我们必须更新A的值和相应S的值。在更新(6,5)中,我们必须将A[6]更改为5,这将导致更改S的值以使S保持最新。
    • 范围和查询很有趣。必须逐个遍历第一个和最后一个切片(部分包含在查询范围中)的元素,但是对于完全包含在我们范围中的切片,我们可以直接使用S中的值并获得性能提升。
    • 在查询(2,14)中,我们得到

  • 更新和查询的代码为:


def查询(S、A、lo、hi、k):
s=0
i=lo
//第1节(从数组A本身获取和,起始部分)

而(i+1)%k!=0和i素数

正如在其他一些答案中提到的,与素数相关的一些基本问题需要O(sqrt(n))时间:

  • 求除数
  • 求除数之和
  • 找到欧拉托蒂
  • 下面我提到两个高级算法,它们在复杂性上也带有sqrt(n)项

    莫氏算法

    请尝试以下问题:

    我的解决方案:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1E6 + 10, k = 500;
    
    struct node {
        int l, r, id;
        bool operator<(const node &a) {
            if(l / k == a.l / k) return r < a.r;
            else return l < a.l;
        }
    } q[N];
    
    long long a[N], cnt[N], ans[N], cur_count;
    void add(int pos) {
        cur_count += a[pos] * cnt[a[pos]];
        ++cnt[a[pos]];
        cur_count += a[pos] * cnt[a[pos]];
    }
    void rm(int pos) {
        cur_count -= a[pos] * cnt[a[pos]];
        --cnt[a[pos]];
        cur_count -= a[pos] * cnt[a[pos]];
    }
    
    int main() {
        int n, t;
        cin >> n >> t;
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        for(int i = 0; i < t; i++) {
            cin >> q[i].l >> q[i].r;
            q[i].id = i;
        }
        sort(q, q + t);
        memset(cnt, 0, sizeof(cnt));
        memset(ans, 0, sizeof(ans));
    
        int curl(0), curr(0), l, r;
        for(int i = 0; i < t; i++) {
            l = q[i].l;
            r = q[i].r;
    
    /* This part takes O(n * sqrt(n)) time */
            while(curl < l)
                rm(curl++);
            while(curl > l)
                add(--curl);
            while(curr > r)
                rm(curr--);
            while(curr < r)
                add(++curr);
    
            ans[q[i].id] = cur_count;
        }
        for(int i = 0; i < t; i++) {
            cout << ans[i] << '\n';
        }
        return 0;
    }
    
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10, k = 333;
    
    vector<int> t[N], ht;
    int tm_, h[N], st[N], nd[N];
    inline int hei(int v, int p) {
        for(int ch: t[v]) {
            if(ch != p) {
                h[ch] = h[v] + 1;
                hei(ch, v);
            }
        }
    }
    inline void tour(int v, int p) {
        st[v] = tm_++;
        ht.push_back(h[v]);
        for(int ch: t[v]) {
            if(ch != p) {
                tour(ch, v);
            }
        }
        ht.push_back(h[v]);
        nd[v] = tm_++;
    }
    
    int n, tc[N];
    vector<int> loc[N];
    long long balance[N];
    vector<pair<long long,long long>> buf;
    inline long long cbal(int v, int p) {
        long long ans = balance[h[v]];
        for(int ch: t[v]) {
            if(ch != p) {
                ans += cbal(ch, v);
            }
        }
        tc[v] += ans;
        return ans;
    }
    inline void bal() {
        memset(balance, 0, sizeof(balance));
        for(auto arg: buf) {
            balance[arg.first] += arg.second;
        }
        buf.clear();
        cbal(1,1);
    }
    
    int main() {
        int q;
        cin >> n >> q;
        for(int i = 1; i < n; i++) {
            int x, y; cin >> x >> y;
            t[x].push_back(y); t[y].push_back(x);
        }
        hei(1,1);
        tour(1,1);
        for(int i = 0; i < ht.size(); i++) {
            loc[ht[i]].push_back(i);
        }
        vector<int>::iterator lo, hi;
        int x, y, type;
        for(int i = 0; i < q; i++) {
            cin >> type;
            if(type == 1) {
                cin >> x >> y;
                buf.push_back(make_pair(x,y));
            }
            else if(type == 2) {
                cin >> x;
                long long ans(0);
                for(auto arg: buf) {
                    hi = upper_bound(loc[arg.first].begin(), loc[arg.first].end(), nd[x]);
                    lo = lower_bound(loc[arg.first].begin(), loc[arg.first].end(), st[x]);
                    ans += arg.second * (hi - lo);
                }
                cout << tc[x] + ans/2 << '\n';
            }
            else assert(0);
    
            if(i % k == 0) bal();
        }
    }
    
    #包括
    使用名称空间std;
    常数N=1E6+10,k=500;
    结构节点{
    int l,r,id;
    布尔运算符>n>>t;
    对于(int i=1;i>a[i];
    }
    for(int i=0;i>q[i].l>>q[i].r;
    q[i].id=i;
    }
    排序(q,q+t);
    memset(cnt,0,sizeof(cnt));
    memset(ans,0,sizeof(ans));
    int curl(0),curr(0),l,r;
    for(int i=0;il)
    加(--curl);
    while(curr>r)
    马币(现钞);;
    while(curr>q;
    对于(int i=1;i>x>>y;
    t[x]。推回(y);t[y]。推回(x);
    }
    hei(1,1);
    旅游(1,1);
    对于(int i=0;i>型;
    如果(类型==1){
    cin>>x>>y;
    buf.向后推(形成一对(x,y));
    }
    else if(类型==2){
    cin>>x;
    长ans(0);
    用于(自动参数:buf){
    hi=上限(loc[arg.first].begin(),loc[arg.first].end(),nd[x]);
    lo=下限(loc[arg.first].begin(),loc[arg.first].end(),st[x]);
    ans+=arg.second*(高-低);
    }
    库特素性检验
    JavaScript中的解决方案
    
    const isPrime = n => {
        for(let i = 2; i <= Math.sqrt(n); i++) {
            if(n % i === 0) return false;
        }
        return true;
    };
    

    const isPrime=n=>{
    for(设i=2;i为素性检验)
    O(sqrt(n))
    
    感谢,这是一个性能稍高的版本,它启发了我。此链接为初学者提供了对O()即O(sqrt n)时间复杂性的基本理解。这是视频中的最后一个示例,但我建议您观看整个视频

    视频中O()即O(sqrt n)时间复杂度算法的最简单示例为:

    p = 0;
    
    for(i = 1; p <= n; i++)
    {
        p = p + i;
    }
    
    p=0;
    
    对于(i=1;p),这个答案实际上是非常错误的。时间复杂度是相对于in的大小来衡量的
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1E6 + 10, k = 500;
    
    struct node {
        int l, r, id;
        bool operator<(const node &a) {
            if(l / k == a.l / k) return r < a.r;
            else return l < a.l;
        }
    } q[N];
    
    long long a[N], cnt[N], ans[N], cur_count;
    void add(int pos) {
        cur_count += a[pos] * cnt[a[pos]];
        ++cnt[a[pos]];
        cur_count += a[pos] * cnt[a[pos]];
    }
    void rm(int pos) {
        cur_count -= a[pos] * cnt[a[pos]];
        --cnt[a[pos]];
        cur_count -= a[pos] * cnt[a[pos]];
    }
    
    int main() {
        int n, t;
        cin >> n >> t;
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
        }
        for(int i = 0; i < t; i++) {
            cin >> q[i].l >> q[i].r;
            q[i].id = i;
        }
        sort(q, q + t);
        memset(cnt, 0, sizeof(cnt));
        memset(ans, 0, sizeof(ans));
    
        int curl(0), curr(0), l, r;
        for(int i = 0; i < t; i++) {
            l = q[i].l;
            r = q[i].r;
    
    /* This part takes O(n * sqrt(n)) time */
            while(curl < l)
                rm(curl++);
            while(curl > l)
                add(--curl);
            while(curr > r)
                rm(curr--);
            while(curr < r)
                add(++curr);
    
            ans[q[i].id] = cur_count;
        }
        for(int i = 0; i < t; i++) {
            cout << ans[i] << '\n';
        }
        return 0;
    }
    
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10, k = 333;
    
    vector<int> t[N], ht;
    int tm_, h[N], st[N], nd[N];
    inline int hei(int v, int p) {
        for(int ch: t[v]) {
            if(ch != p) {
                h[ch] = h[v] + 1;
                hei(ch, v);
            }
        }
    }
    inline void tour(int v, int p) {
        st[v] = tm_++;
        ht.push_back(h[v]);
        for(int ch: t[v]) {
            if(ch != p) {
                tour(ch, v);
            }
        }
        ht.push_back(h[v]);
        nd[v] = tm_++;
    }
    
    int n, tc[N];
    vector<int> loc[N];
    long long balance[N];
    vector<pair<long long,long long>> buf;
    inline long long cbal(int v, int p) {
        long long ans = balance[h[v]];
        for(int ch: t[v]) {
            if(ch != p) {
                ans += cbal(ch, v);
            }
        }
        tc[v] += ans;
        return ans;
    }
    inline void bal() {
        memset(balance, 0, sizeof(balance));
        for(auto arg: buf) {
            balance[arg.first] += arg.second;
        }
        buf.clear();
        cbal(1,1);
    }
    
    int main() {
        int q;
        cin >> n >> q;
        for(int i = 1; i < n; i++) {
            int x, y; cin >> x >> y;
            t[x].push_back(y); t[y].push_back(x);
        }
        hei(1,1);
        tour(1,1);
        for(int i = 0; i < ht.size(); i++) {
            loc[ht[i]].push_back(i);
        }
        vector<int>::iterator lo, hi;
        int x, y, type;
        for(int i = 0; i < q; i++) {
            cin >> type;
            if(type == 1) {
                cin >> x >> y;
                buf.push_back(make_pair(x,y));
            }
            else if(type == 2) {
                cin >> x;
                long long ans(0);
                for(auto arg: buf) {
                    hi = upper_bound(loc[arg.first].begin(), loc[arg.first].end(), nd[x]);
                    lo = lower_bound(loc[arg.first].begin(), loc[arg.first].end(), st[x]);
                    ans += arg.second * (hi - lo);
                }
                cout << tc[x] + ans/2 << '\n';
            }
            else assert(0);
    
            if(i % k == 0) bal();
        }
    }
    
    const isPrime = n => {
        for(let i = 2; i <= Math.sqrt(n); i++) {
            if(n % i === 0) return false;
        }
        return true;
    };
    
    p = 0;
    
    for(i = 1; p <= n; i++)
    {
        p = p + i;
    }