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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

牛客网【每日一题】4月30日题目精讲 换个角度思考

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网【每日一题】4月30日题目精讲 换个角度思考 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈接:

文章目錄

    • 題目描述
    • 題解:
    • 主席樹做法:
    • 代碼:
    • 樹狀數組:
    • 更扯淡的方法!!!

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 262144K,其他語言524288K 64bit IO Format: %lld

題目描述

輸入描述:

第一行兩個整數n,m 第二行n個整數表示序列a的元素,序列下標從1開始標號,保證1 ≤ ai ≤ 105
之后有m行,每行三個整數(l,r,k),保證1 ≤ l ≤ r ≤ n,且1 ≤ k ≤ 105

輸出描述:

對于每一個詢問,輸出一個整數表示答案后回車

示例1
輸入

5 1 1 2 3 4 5 1 5 3

輸出

3

備注:
數據范圍
1 ≤ n ≤ 105
1 ≤ m ≤ 105

題解:

主席樹,樹狀數組等都可以做

主席樹做法:

簡單提一句主席樹
主席樹的本體其實是線段樹,也就是很多棵線段樹,用以存一段數字區間出現次數,主席樹經常用于求一個序列內的第 k 小
在這里,主席樹就是提前預處理好每個點的權值線段樹,查詢時,可以直接用r時刻前綴小于x的數量減去l-1的數量,剩下的就是[l,r]區間值
也就是[L,R]=[1,R]-[1,L-1],查詢后兩者相減即可

#include <bits/stdc++.h> using namespace std; const int maxn=1e5+2; int n,m; int a[maxn]; vector<int>edge[maxn*4];void build(int id,int l,int r) {edge[id].clear();for(int i=l;i<=r;i++) edge[id].push_back(a[i]);sort(edge[id].begin(),edge[id].end());if(l==r) return;int mid=(l+r)>>1;build(id<<1,l,mid);build(id<<1|1,mid+1,r); }//建樹 int query(int id,int L,int R,int l,int r,int k) { int sum=0;vector<int>::iterator it;if(l<=L&&R<=r){it=upper_bound(edge[id].begin(),edge[id].end(),k);//二分查找,第一個大于k的數,返回地址 return it-edge[id].begin();//兩者做差的個數}int mid=(L+R)/2;if(l<=mid){sum+=query(id*2,L,mid,l,r,k);}if(mid<r){sum+=query(id*2,mid+1,R,l,r,k);} return sum; } int main() { int l,r,k;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);while(m--){cin>>l>>r>>k;printf("%d\n",query(1,1,n,l,r,k));}return 0; }

代碼:

樹狀數組:

首先需要離線操作,我們每次查詢都是要知道左右區間以及x,相當于同時有兩個東西未知需要操作。通過離散后,我們可以控制其中一部分,另外一部分未知變化,例如:第一種我們查詢[l,r]內有多少數滿足條件,我們就要保證所有數都小于x;第二種如何問有多少數小于等于x,就保證范圍取定于[l,r]。這樣更高效,當然占空間更多。

簡單的說:
離線操作:讀入所有的操作數據,然后一次性處理。
在線操作:每讀入一個操作數據,就進行一次操作。

第一種:
我們在保證所有數都是小于等于x的情況下來查詢[l,r]有多少個數
每次詢問[l,r,x]之前,把小于等于x的ai都加入加入到一個另外的位置上,這樣里面存放的都是滿足條件的數,直接詢問即可

第二種:
保證所有數都在[l,r]區間的情況下,查詢小于等于x的數量
我們可以在離線時,將[l,r]區間問題轉化成 [ 1 , l-1 ] , [ 1 , r ] 兩個區間,這樣就可以用樹狀數組來解決

(這是鄧老師的講解,我加入自己的理解寫出來的)

代碼寫完再更

更扯淡的方法!!!

這題貌似優化暴力就能過。。。
就是直接模擬,不知為啥過了。。快讀都還沒用上

#include <bits/stdc++.h> using namespace std; typedef long long ll;const int N = 1e5 + 3; int a[N];int main() {int n,m;cin>>n>>m;for (int i = 1; i <= n; ++i) cin>>a[i]; while (m--) {int l,r,k;cin>>l>>r>>k;int sum = 0;for (int i = l; i <= r; ++i)if (a[i] <= k) ++sum;printf("%d\n", sum);}return 0; }

總結

以上是生活随笔為你收集整理的牛客网【每日一题】4月30日题目精讲 换个角度思考的全部內容,希望文章能夠幫你解決所遇到的問題。

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