第几小
#include <iostream> #include <vector> #include <cmath> #include <algorithm> using namespace std; int main() { // 请在此输入您的代码 int n; cin>>n; //块长 int len=sqrt(n)*log(n)/2; //块数 int k=(n%len==0)?n/len:n/len+1; //分块 vector<int> block[k+1]; //第i个数属于的块 vector<int> belong(n+1,0); vector<int> a(n+1,0); int blockNum=0; for(int i=1;i<=n;i++){ cin>>a[i]; blockNum=(i-1)/len+1; belong[i]=blockNum; block[blockNum].push_back(a[i]); } //对分块进行排序 for(int i=1;i<=k;i++){ sort(block[i].begin(),block[i].end(),less<int>()); } //记录操作 int m; cin>>m; vector<vector<int>> op(m,vector<int>(4,0)); for(int i=0;i<m;i++){ cin>>op[i][0]; if(op[i][0]==1){ //修改操作 for(int j=1;j<=2;j++){ cin>>op[i][j]; } }else{ //查询操作 for(int j=1;j<=3;j++){ cin>>op[i][j]; } } } //执行操作 vector<int> res; int num1,num2,num3; num1=num2=num3; int count=0; int mid=0; for(int i=0;i<m;i++){ num1=op[i][1]; num2=op[i][2]; num3=op[i][3]; if(op[i][0]==1){ //修改分组 auto it=lower_bound(block[belong[num1]].begin(),block[belong[num1]].end(),a[num1]); block[belong[num1]].erase(it); it=lower_bound(block[belong[num1]].begin(),block[belong[num1]].end(),num2); if(it==block[belong[num1]].end()){ block[belong[num1]].push_back(num2); }else{ block[belong[num1]].insert(it,num2); } //修改原序列 a[num1]=num2; }else{ count=0; mid=a[num3]; //先查左右两端分块中满足条件的元组数,因为num1和num2所在的块不一定一整块都参与比较 for(int j=num1;j<=min(num2,belong[num1]*len);j++){ if(a[j]<mid){ count++; } } if(belong[num1]!=belong[num2]){ for(int j=(belong[num2]-1)*len+1;j<=num2;j++){ if(a[j]<mid){ count++; } } } //区间查询,用二分法查询每个块中小于a[p]的元素个数 for(int j=belong[num1]+1;j<=belong[num2]-1;j++){ count+=lower_bound(block[j].begin(),block[j].end(),a[num3])-block[j].begin(); } res.push_back(count+1); //49 31 31 11 24 8 4 62 7 11 46 47 3 20 16 24 29 11 2 4 5 16 3 68 } } for(auto &&num:res){ cout<<num<<" "; } return 0; }