小易在维护数据的时候遇到一个需求,具体来说小易有一系列数据,这些数据了构成一个长度为n的数字序列,接下来小易会在这个序列上进行q次操作。
每次操作有一个查询的数字x,小易需要将序列数据中所有大于等于x的数字都减一,并输出在本次操作中有多少个数字被减一了。
小易犯了难,希望你能帮帮他。
第一行n,q,表示数字个数和操作个数。
接下来一行n个数表示初始的数字。
接下来q行,每行一个数,表示指定的数字x。,
对于每个询问,输出一个数字表示答案
4 3 1 2 3 4 4 3 1
1 2 4
3 2 1 2 3 3 3
1 0
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=2e5+5; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) int sum[N<<2],add[N<<2]; int a[N]; void pushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int l,int r,int rt) { if(l==r) { sum[rt]=a[l]; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); pushUp(rt); } void pushDown(int rt,int ln,int rn) { if(add[rt]) { add[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt]; sum[rt<<1]+=add[rt]*ln; sum[rt<<1|1]+=add[rt]*rn; add[rt]=0; } } void update(int L,int R,int C,int l,int r,int rt) { if(L <= l && r <= R) { sum[rt]+=C*(r-l+1); add[rt]+=C; return ; } int m=(l+r)>>1; pushDown(rt,m-l+1,r-m); if(L <= m) update(L,R,C,l,m,rt<<1); if(R > m) update(L,R,C,m+1,r,rt<<1|1); pushUp(rt); } int query(int L,int R,int l,int r,int rt) { if(L <= l && r <= R) { return sum[rt]; } int m=(l+r)>>1; pushDown(rt,m-l+1,r-m); int ans=0; if(L <= m) ans+=query(L,R,l,m,rt<<1); if(R > m) ans+=query(L,R,m+1,r,rt<<1|1); return ans; } int main() { std::ios::sync_with_stdio(false); int n,q; while(cin>>n>>q) { memset(add,0,sizeof(add)); for(int i=1; i<=n; i++) { cin>>a[i]; } sort(a+1,a+1+n); build(1,n,1); while(q--) { int l=1,r=n,m,ans=-1,x; cin>>x; while(l<=r) { m=(l+r)>>1; if(query(m,m,1,n,1)>=x) { r=m-1; ans=m; } else { l=m+1; } } if(ans==-1) { cout<<0<<endl; } else { cout<<n-ans+1<<endl; update(ans,n,-1,1,n,1); } } } return 0; }
n = list(map(int, input().split(' '))) len = n[0] N = n[1] data = list(map(int, input().split(' '))) while N: N = N-1 num = 0 val = int(input()) for i in range(len): if(data[i] >= val): data[i] = data[i] - 1 num = num+1 print(num)
c = input('数字个数和操作次数:') d = c.split(' ') n,q = int(d[0]),int(d[1]) a = input('请输入初始数:') b = a.split(' ', n) list1 = [] for i in b: list1.append(int(i)) list2 = [] while q: x = int(input('指定数字:')) list2.append(x) q -= 1 for k in list2: list3 = [] count = 0 for j in list1: if j >= k: list3.append(j-1) count += 1 else: list3.append(j) list1 = list3.copy() print('有' + str(count) + '个数字被减一。')我调试了好久,终于写出来了。
import java.util.Scanner; import java.util.Arrays; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(), q = sc.nextInt(); int[] arr = new int[n]; for(int i = 0; i < n; i++) arr[i] = sc.nextInt(); Arrays.sort(arr); // 对数组按升序排列,防止之后每次查找都需要遍历一遍数组 // 开始q次减一操作 for(int i = 0; i < q; i++){ int opNum = sc.nextInt(); System.out.println(solve(arr, opNum)); } } private static int solve(int[] arr, int q) { int count = 0; // 从后往前遍历不会浪费查找 for(int i = arr.length - 1; i >= 0; i--){ if(arr[i] >= q){ arr[i] -= 1; count ++; }else break; // 遇到小于q的数直接退出循环 } return count; } }
import sys b = []#b存储第三行及之后的数据 n,p = map(int,sys.stdin.readline().strip().split()) a = list(map(int,sys.stdin.readline().strip().split())) #a存储第二行数据 for i in range(p): b.append(int(sys.stdin.readline().strip())) for i in range(p): k = 0 for j in range(n): if a[j] >= b[i]: a[j] -= 1 k += 1 print(k)
# 好笨的方法,别笑话我,加油 n = int(input("n = ")) q = int(input("q = ")) list1 = [i for i in range(1,n+1)] for i in range(q): x = int(input("第" + str(i+1) + "次输入:")) num = 0 list2 = [] for c in list1: if c >= x: list2.append(c-1) num = num + 1 else: list2.append(c) print("本次操作中有{}个数被减一!".format(num)) list1 = list2.copy()
#include <bits/stdc++.h> using namespace std; class segtree{ public: int n; int* data; int* tree; int* lazy; segtree(int* arr, int _n) : n(_n) { data = new int[_n]; tree = new int[_n * 4]; lazy = new int[_n * 4]; fill_n(tree, _n * 4, 0); fill_n(lazy, _n * 4, 0); for (int i = 0; i < _n; i++) { data[i] = arr[i]; } build(0, 0, n - 1); } ~segtree() { delete []data; delete []tree; delete []lazy; } void push(int tId) { tree[tId] = tree[tId * 2 + 1] + tree[tId * 2 + 2]; } void pull(int tId, int l, int r) { int mid = (l + r) / 2; tree[tId * 2 + 1] += (mid - l + 1) * lazy[tId]; tree[tId * 2 + 2] += (r - mid) * lazy[tId]; lazy[tId * 2 + 1] += lazy[tId]; lazy[tId * 2 + 2] += lazy[tId]; lazy[tId] = 0; } void build(int tId, int l, int r) { if (l == r) { tree[tId] = data[l]; return; } int mid = (l + r) / 2; build(tId * 2 + 1, l, mid); build(tId * 2 + 2, mid + 1, r); push(tId); } int get(int tId, int l, int r, int x) { if (l == r && l == x) { return tree[tId]; } if (lazy[tId]) { pull(tId, l, r); } int mid = (l + r) / 2; if (x <= mid) { return get(tId * 2 + 1, l, mid, x); } else { return get(tId * 2 + 2, mid + 1, r, x); } } void modify(int tId, int l, int r, int ml, int mr, int v) { if (ml <= l && r <= mr) { tree[tId] += (r - l + 1) * v; lazy[tId] += v; return; } if (lazy[tId] != 0) { pull(tId, l, r); } int mid = (l + r) >> 1; if (mr <= mid) { modify((tId * 2) + 1, l, mid, ml, mr, v); } else if (ml > mid) { modify((tId * 2) + 2, mid + 1, r, ml, mr, v); } else { modify((tId * 2) + 1, l, mid, ml, mid, v); modify((tId * 2) + 2, mid + 1, r, mid + 1, mr, v); } push(tId); } }; int arr[234567]; int main() { int n, q; cin >> n >> q; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); } sort(arr, arr + n); segtree st(arr, n); while (q--) { int x; int l = 0, r = n - 1; scanf("%d", &x); while (l <= r) { int mid = (l + r) >> 1; if (st.get(0, 0, n - 1, mid) < x) l = mid + 1; else r = mid - 1; } if (l >= n) { cout << "0" << "\n"; } else { cout << n - 1 - l + 1 << "\n"; st.modify(0, 0, n - 1, l, n - 1, -1); } } return 0; }
#include <bits/stdc++.h> using namespace std; const int N = 200010; int a[N], hs[N]; int n, q, x; int main() { scanf("%d%d", &n, &q); int x; for (int i = 1; i <= n; ++ i) { scanf("%d", &a[i]); } sort(a + 1, a + n + 1, greater<int>()); while (q -- ) { scanf("%d", &x); int ret = 0; for (int i = 1; i <= n; ++ i) { if (a[i] >= x) { a[i] -= 1; ret ++ ; } else { break; } } printf("%d\n", ret); } return 0; }
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int q = scanner.nextInt(); int[] arr = new int[n]; //将数字录入数组 for (int i = 0; i < n; i++) { int num = scanner.nextInt(); arr[i] = num; } //先将数组排序 Arrays.sort(arr); //查询次数 for (int i = 0; i < q; i++) { //需要查询的数字 int x = scanner.nextInt(); System.out.println(demo4(arr, x)); } } public static int demo4(int[] arr, int x) { int count = 0; //从大往小比较,碰到小于x的及时终止循环,能优化时间 for (int i = arr.length-1; i >= 0; i--) { if (arr[i] >= x) { arr[i]--; count++; } else { break; } } return count; } }
#include <bits/stdc++.h> using namespace std; using ll = long long; class SegmentTree { vector<int> data; struct TreeNode { int sum; int add; }; vector<TreeNode> tree; public: template <typename T> SegmentTree(T&& data) : data(forward<T>(data)) { int n = this->data.size(); tree.resize(n * 4); build(0, 0, n - 1); } private: // [l,r]表示idx掌管的区间 void build(int idx, int l, int r) { if (l == r) { tree[idx].sum = data[l]; tree[idx].add = 0; } else { int mid = getMiddle(l, r); // 递归左右区间 build(childLeft(idx), l, mid); build(childRight(idx), mid + 1, r); // 左右区间都建立好了,更新idx即可 update(idx); } } /* idx表示当前树节点的索引 l,r表示idx掌管的区间 s,t表示要获取[l,r]区间在[s,t]范围内的和 */ int query(int idx, int l, int r, int s, int t) { if (s <= l && r <= t) { // 直接返回即可 return tree[idx].sum; } pushdown(idx, l, r); int mid = getMiddle(l, r), ans = 0; if (mid >= s) ans += query(childLeft(idx), l, mid, s, t); if (mid < t) ans += query(childRight(idx), mid + 1, r, s, t); return ans; } /* idx表示当前树节点的索引 l,r表示idx掌管的区间 s,t表示要在[s,t]上都加上一个数 */ void add(int idx, int l, int r, int s, int t, int val) { if (s <= l && r <= t) { // 直接加上即可 tree[idx].add += val; tree[idx].sum += val * (r - l + 1); return; } pushdown(idx, l, r); int mid = getMiddle(l, r); if (mid >= s) add(childLeft(idx), l, mid, s, t, val); if (mid < t) add(childRight(idx), mid + 1, r, s, t, val); update(idx); } // 使得tree[idx].sum是正确的 void update(int idx) { tree[idx].sum = tree[childLeft(idx)].sum + tree[childRight(idx)].sum; } // 将tree[idx].add传递给左右节点,确保左右节点的add是正确的 void pushdown(int idx, int l, int r) { auto& root = tree[idx]; int mid = getMiddle(l, r); int lc = childLeft(idx); int rc = childRight(idx); auto &lr = tree[lc], &rr = tree[rc]; lr.sum += root.add * (mid - l + 1); lr.add += root.add; rr.sum += root.add * (r - mid); rr.add += root.add; root.add = 0; } // 获取左子节点 static int childLeft(int index) { return index * 2 + 1; } // 获取右子节点 static int childRight(int index) { return index * 2 + 2; } // 平分[l,r]为[l,mid] , [mid+1,r] , 返回mid static int getMiddle(int l, int r) { return l + (r - l) / 2; } public: int get(int idx) { return query(0, 0, data.size() - 1, idx, idx); } // 在[l,r]区间加上某个值 void add(int l, int r, int val) { add(0, 0, data.size() - 1, l, r, val); } }; int main() { int n, q, x; cin >> n >> q; vector<int> a(n); for (auto& v : a) cin >> v; sort(a.begin(), a.end()); SegmentTree tree(move(a)); // 线段树+二分 while (q--) { cin >> x; auto deal = [&]() { if (tree.get(n - 1) < x) return 0; // 查询>=x的最小下标 // 二分查找满足条件的最小值,lr左闭右开 int l = 0, r = n; while (l + 1 < r) { int mid = l + ((r - l) >> 1); tree.get(mid) >= x ? r = mid : l = mid; } if (r == 1 && tree.get(0) >= x) --r; tree.add(r, n - 1, -1); // cout << "find : " << r << endl; return n - r; }; cout << deal() << endl; // cout << "seq : "; // for (int i = 0; i < n; ++i) cout << tree.get(i) << ' '; // cout << endl; } return 0; }
随机生成几组数试了一下 import random import numpy as np n=random.randint(1,20) x=np.random.randint(1,10,random.randint(1,10)) s=np.random.randint(1,20,n) for i in x: print(len(s[s>=i])) s=np.where(s>=i,s-1,s)
n,q=map(int,input().split()) arr=list(map(int,input().split())) arr.sort() flag=0 for i in range(q): x=int(input()) if x in arr: t=arr.index(x) arr[t:n]=[m-1 for m in arr[t:n]] print(n-t) else: for j in range(n): if arr[j]>=x: arr[j:n]=[m-1 for m in arr[j:n]] flag=1 print(n-j) break if flag==0: print(0)
#include<iostream> #include<algorithm> using namespace std; int main(){ int n,q,pos,x; cin>>n>>q; int*a=new int[n]; for(int i=0;i<n;i++) cin>>a[i]; sort(a,a+n); while(q-->0){ cin>>x; pos=lower_bound(a,a+n,x)-a; cout<<n-pos<<endl; for(;pos<n;pos++) a[pos]--; } return 0; }
nq = input().split(" ") n = int(nq[0]) q = int(nq[1]) def juge(x,datalist): rst = 0 for i in range(len(datalist)): if datalist[i] >= x: rst += 1 datalist[i] = datalist[i]-1 return rst,datalist result = [] sn = list(map(int,input().split(" "))) for i in range(q): x = int(input().split(" ")[0]) rst,sn = juge(x,sn) result.append(rst) for j in result: print(j)求解答,我哪里出问题了?感觉在自己的IDE能正常运行呀
import java.util.Arrays; import java.util.Scanner; public class Main{ static int search(int[] array,int value) { int left=0; int right=array.length-1; int mid=0; while(left<=right) { mid=(left+right)>>1; if(value<=array[mid]) right=mid-1; else left=mid+1; } return left<array.length?left:array.length; } public static void main(String[] args){ Scanner scanner=new Scanner(System.in); int n=scanner.nextInt(); int q=scanner.nextInt(); int[] a=new int[n]; for(int i=0;i<n;i++) a[i]=scanner.nextInt(); Arrays.sort(a); for(int i=0;i<q;i++) { int x=scanner.nextInt(); int ind=search(a, x); System.out.println(n-ind); for(int j=ind;j<n;j++) a[j]--; } } }
while(line1 = readline()){ let line1Arr = line1.split(' '); let n = parseInt(line1Arr[0]); let q = parseInt(line1Arr[1]); let arr = readline().split(' ').map((it)=>parseInt(it)); for(let i=0;i<q;i++){ let x = parseInt(readline()); let count = 0; arr.forEach((val,index)=>{ if(val >= x){ count++; arr[index] = --val; } }) print(count); } } 用js总是通不过是为什么啊,我实在是看不出有什么问题??
n,q = list(map(int, input().split(' '))) if n != '': nums = sorted(list(map(int, input().split(' '))),reverse=True) for _ in range(q): x = int(input()) res = 0 for i in range(n): if nums[i] >= x: nums[i] -= 1 res += 1 else: break print(res)