在考试前要看!
首先是平衡树,然后是整除分块
//最终版本
#include<iostream>
#include<cstdio>
#include<cstring>
typedef long long ll;
using namespace std;
ll n,m;
struct Splay{
#define N (ll)12e6
ll siz[N],fa[N],son[N][3],vul[N],tot,root,cnt[N];
void UP(ll x){
siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];
}
bool dir(ll x){
return son[fa[x]][1]==x;
}
void rotate(ll x){
ll y=fa[x],z=fa[y],k=dir(x),w=son[x][k^1];
fa[x]=z,son[z][dir(y)]=x;
fa[y]=x,son[x][k^1]=y;
fa[w]=y,son[y][k]=w;
UP(y),UP(x);
}
void splay(ll x,ll goal=0){
while(fa[x]!=goal){
ll y=fa[x],z=fa[y];
if(z!=goal){
if(dir(x)==dir(y))rotate(y);
else rotate(x);
}
rotate(x);
}
if(goal==0)root=x;
}
void find(ll x){
if(!root)return ;
ll cur=root;
while(son[cur][x>vul[cur]]&&x!=vul[cur])
cur=son[cur][x>vul[cur]];
splay(cur);
}
ll LR(ll x,ll k){
find(x);
if(k==0&&vul[root]<x)return root;
if(k==1&&vul[root]>x)return root;
ll cur=son[root][k];
while(son[cur][k^1])cur=son[cur][k^1];
return cur;
}
void insert(ll x){
ll cur=root,p=0;
while(cur&&x!=vul[cur]){
p=cur;
cur=son[cur][x>vul[cur]];
}
if(cur)cnt[cur]++;
else {
cur=++tot;
if(p)son[p][x>vul[p]]=cur;
siz[cur]=cnt[cur]=1;
son[cur][0]=son[cur][1]=0;
fa[cur]=p,vul[cur]=x;
}
splay(cur);
}
void Delete(ll x){
ll le=LR(x,0),re=LR(x,1);
splay(le),splay(re,le);
ll del=son[re][0];
if(cnt[del]>1)cnt[del]--,splay(del);//注意是大于1
//splay(del)更新路上所有点的信息
else son[re][0]=0;
UP(re),UP(le);
}
ll Kth(ll k){
ll cur=root;
while(1){
if(k<=siz[son[cur][0]]&&son[cur][0])
cur=son[cur][0];
else if(k>siz[son[cur][0]]+cnt[cur]){
k-=siz[son[cur][0]]+cnt[cur];
cur=son[cur][1];
}
else return cur;
}
}
ll get_rank(ll x){
find(x);
if(vul[root]<x)return siz[son[root][0]]+cnt[root];
else return siz[son[root][0]];
}
}T;
int main(){
cin>>n;
T.insert(1e8);
T.insert(-1e8);
for(ll i=1;i<=n;i++){
ll a1,a2;
scanf("%lld%lld",&a1,&a2);
switch(a1){
case 1:T.insert(a2);break;
case 2:T.Delete(a2);break;
case 3:printf("%lld\n",T.get_rank(a2));break;
case 4:printf("%lld\n",T.vul[T.Kth(a2+1)]);break;
case 5:printf("%lld\n",T.vul[T.LR(a2,0)]);break;
case 6:printf("%lld\n",T.vul[T.LR(a2,1)]);break;
}
}
}
for(ll i=1;i<=n;i++){
ll r;
for(ll l=1;l<=m;l=r){
r=max(l+1,a[i]/(a[i]/l)+1);
vec[i].push_back(a[i]/l);
}
}
在半分钟内写完减少能量消耗的树状数组
struct ST{
ll f[N];
ll lowbits(ll x){return x&-x;}
ll inquire(ll x,ll tmp=0){
for(;x;x-=lowbits(x))(tmp+=f[x])%=mod;
return tmp;
}
ll query(ll l,ll r){
if(r<l)return 0;
return (inquire(r)-inquire(l-1)+mod)%mod;
}
void modify(ll x,ll del){
for(;x<=n;x+=lowbits(x))(f[x]+=del)%=mod;
}
}T;
敲响警钟:矩阵乘法需要累乘的时候要把答案矩阵写在左边,此时答案矩阵是一个横矩阵(大概吧)
逆元递推
\[inv[i]=(mod-mod/i)*inv[mod\%i]\%mod (其中M为模数,要求为奇质数)
\]
\[inv[1]=1;
\]